spectrum-ts 0.9.0 → 1.0.1

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.
@@ -1,22 +1,23 @@
1
1
  import {
2
+ asGroup,
2
3
  asRichlink
3
- } from "../../chunk-6ZOLTQDN.js";
4
+ } from "../../chunk-LAGNM6I7.js";
4
5
  import {
6
+ cloud,
7
+ mergeStreams,
8
+ stream
9
+ } from "../../chunk-2Y5GBI6W.js";
10
+ import {
11
+ UnsupportedError,
5
12
  asAttachment,
6
13
  asContact,
7
14
  asCustom,
8
15
  asReaction,
9
- cloud,
16
+ asText,
17
+ definePlatform,
10
18
  fromVCard,
11
- mergeStreams,
12
- stream,
13
19
  toVCard
14
- } from "../../chunk-CZIWNTXP.js";
15
- import {
16
- UnsupportedError,
17
- asText,
18
- definePlatform
19
- } from "../../chunk-PLJI5FTO.js";
20
+ } from "../../chunk-XMAI2AAN.js";
20
21
 
21
22
  // src/providers/imessage/index.ts
22
23
  import { createClient as createClient2, directChat } from "@photon-ai/advanced-imessage";
@@ -249,6 +250,7 @@ var send = async (client, spaceId, content) => {
249
250
  throw UnsupportedError.content(content.type, "iMessage (local mode)");
250
251
  }
251
252
  };
253
+ var getMessage = async (_client, _id) => void 0;
252
254
 
253
255
  // src/providers/imessage/remote.ts
254
256
  import {
@@ -380,10 +382,52 @@ var ensureM4a = async (buffer, mimeType) => {
380
382
  return transcodeToM4a(buffer);
381
383
  };
382
384
 
385
+ // src/providers/imessage/cache.ts
386
+ var DEFAULT_MAX = 1e3;
387
+ var MessageCache = class {
388
+ map = /* @__PURE__ */ new Map();
389
+ max;
390
+ constructor(max = DEFAULT_MAX) {
391
+ this.max = max;
392
+ }
393
+ get(id) {
394
+ return this.map.get(id);
395
+ }
396
+ set(id, message) {
397
+ if (this.map.has(id)) {
398
+ this.map.delete(id);
399
+ }
400
+ this.map.set(id, message);
401
+ if (this.map.size > this.max) {
402
+ const first = this.map.keys().next().value;
403
+ if (first !== void 0) {
404
+ this.map.delete(first);
405
+ }
406
+ }
407
+ }
408
+ clear() {
409
+ this.map.clear();
410
+ }
411
+ };
412
+ var caches = /* @__PURE__ */ new WeakMap();
413
+ var getMessageCache = (owner) => {
414
+ let cache = caches.get(owner);
415
+ if (!cache) {
416
+ cache = new MessageCache();
417
+ caches.set(owner, cache);
418
+ }
419
+ return cache;
420
+ };
421
+
383
422
  // src/providers/imessage/remote.ts
384
423
  var PLATFORM = "iMessage";
385
424
  var URL_BALLOON_BUNDLE_ID = "com.apple.messages.URLBalloonProvider";
386
- var unsupportedContent = (type) => UnsupportedError.content(type, PLATFORM);
425
+ var GROUP_ITEM_ALLOWED = /* @__PURE__ */ new Set([
426
+ "attachment",
427
+ "contact",
428
+ "voice"
429
+ ]);
430
+ var unsupportedContent = (type, detail) => UnsupportedError.content(type, PLATFORM, detail);
387
431
  var toSendResult = (receipt) => ({
388
432
  id: receipt.guid,
389
433
  timestamp: /* @__PURE__ */ new Date()
@@ -442,14 +486,19 @@ var getAssociatedMessageType = (message) => {
442
486
  const fromRaw = raw?.associatedMessageType;
443
487
  return typeof fromRaw === "string" ? fromRaw : void 0;
444
488
  };
445
- var baseMessage = (event) => ({
446
- sender: { id: event.message.sender?.address ?? "" },
447
- space: {
448
- id: event.chatGuid,
449
- type: event.chatGuid.includes(";+;") ? "group" : "dm"
450
- },
451
- timestamp: event.timestamp
452
- });
489
+ var getBalloonBundleId = (message) => {
490
+ const raw = message._raw;
491
+ const id = raw?.balloonBundleId;
492
+ return typeof id === "string" ? id : void 0;
493
+ };
494
+ var resolveChatGuid = (message, hint) => {
495
+ if (hint) {
496
+ return hint;
497
+ }
498
+ const first = message.chatGuids?.[0];
499
+ return first ?? "";
500
+ };
501
+ var resolveSenderId = (message) => message.sender?.address ?? "";
453
502
  var toAttachmentContent2 = (client, info) => asAttachment({
454
503
  name: info.fileName,
455
504
  mimeType: info.mimeType,
@@ -465,10 +514,87 @@ var toVCardContent2 = async (client, info) => {
465
514
  return toAttachmentContent2(client, info);
466
515
  }
467
516
  };
468
- var getBalloonBundleId = (message) => {
469
- const raw = message._raw;
470
- const id = raw?.balloonBundleId;
471
- return typeof id === "string" ? id : void 0;
517
+ var attachmentContent = async (client, info) => isVCardAttachment2(info.mimeType, info.fileName) ? await toVCardContent2(client, info) : toAttachmentContent2(client, info);
518
+ var baseShape = (message, chatGuidHint, timestamp) => {
519
+ const chat = resolveChatGuid(message, chatGuidHint);
520
+ return {
521
+ sender: { id: resolveSenderId(message) },
522
+ space: {
523
+ id: chat,
524
+ type: chat.includes(";+;") ? "group" : "dm"
525
+ },
526
+ timestamp
527
+ };
528
+ };
529
+ var buildAttachmentMessage = async (client, base, info, id, partIndex, parentId) => {
530
+ const content = await attachmentContent(client, info);
531
+ const msg = { ...base, id, content, partIndex };
532
+ if (parentId !== void 0) {
533
+ msg.parentId = parentId;
534
+ }
535
+ return msg;
536
+ };
537
+ var rebuildFromAppleMessage = async (client, message, chatGuidHint) => {
538
+ const messageGuidStr = message.guid;
539
+ const timestamp = message.dateCreated ?? /* @__PURE__ */ new Date();
540
+ const base = baseShape(message, chatGuidHint, timestamp);
541
+ if (message.attachments.length === 1) {
542
+ const info = message.attachments[0];
543
+ if (!info) {
544
+ throw new Error("Unreachable: attachments.length === 1 but no element");
545
+ }
546
+ return buildAttachmentMessage(client, base, info, messageGuidStr, 0);
547
+ }
548
+ if (message.attachments.length > 1) {
549
+ const items = [];
550
+ for (let i = 0; i < message.attachments.length; i++) {
551
+ const info = message.attachments[i];
552
+ if (!info) {
553
+ continue;
554
+ }
555
+ items.push(
556
+ await buildAttachmentMessage(
557
+ client,
558
+ base,
559
+ info,
560
+ formatChildId(i, messageGuidStr),
561
+ i,
562
+ messageGuidStr
563
+ )
564
+ );
565
+ }
566
+ return {
567
+ ...base,
568
+ id: messageGuidStr,
569
+ content: asGroup({ items })
570
+ };
571
+ }
572
+ const text = message.text;
573
+ if (getBalloonBundleId(message) === URL_BALLOON_BUNDLE_ID) {
574
+ const url = text ?? "";
575
+ try {
576
+ return { ...base, id: messageGuidStr, content: asRichlink({ url }) };
577
+ } catch {
578
+ return {
579
+ ...base,
580
+ id: messageGuidStr,
581
+ content: url ? asText(url) : asCustom(message)
582
+ };
583
+ }
584
+ }
585
+ return {
586
+ ...base,
587
+ id: messageGuidStr,
588
+ content: text ? asText(text) : asCustom(message)
589
+ };
590
+ };
591
+ var cacheMessage = (cache, message) => {
592
+ cache.set(message.id, message);
593
+ if (message.content.type === "group") {
594
+ for (const item of message.content.items) {
595
+ cache.set(item.id, item);
596
+ }
597
+ }
472
598
  };
473
599
  var toRichlinkMessage = (event, base, id) => {
474
600
  const url = event.message.text ?? "";
@@ -482,8 +608,42 @@ var toRichlinkMessage = (event, base, id) => {
482
608
  };
483
609
  }
484
610
  };
485
- var PART_PREFIX = /^p:\d+\//;
486
- var toReactionMessage = (event, base, id, target) => {
611
+ var PART_PREFIX = /^p:(\d+)\//;
612
+ var formatChildId = (partIndex, parentGuid) => `p:${partIndex}/${parentGuid}`;
613
+ var parseTapbackTarget = (target) => {
614
+ const match = target.match(PART_PREFIX);
615
+ const guid = target.replace(PART_PREFIX, "");
616
+ const partIndex = match ? Number(match[1]) : 0;
617
+ return { guid, partIndex };
618
+ };
619
+ var parseChildId = (id) => {
620
+ const match = id.match(PART_PREFIX);
621
+ if (!match) {
622
+ return null;
623
+ }
624
+ return {
625
+ parentGuid: id.replace(PART_PREFIX, ""),
626
+ partIndex: Number(match[1])
627
+ };
628
+ };
629
+ var resolveReactionTarget = async (client, cache, strippedGuid, partIndex) => {
630
+ let candidate = cache.get(strippedGuid);
631
+ if (!candidate) {
632
+ try {
633
+ const fetched = await client.messages.get(messageGuid(strippedGuid));
634
+ candidate = await rebuildFromAppleMessage(client, fetched);
635
+ cacheMessage(cache, candidate);
636
+ } catch {
637
+ return;
638
+ }
639
+ }
640
+ if (candidate.content.type === "group") {
641
+ const item = candidate.content.items[partIndex];
642
+ return item ?? candidate;
643
+ }
644
+ return candidate;
645
+ };
646
+ var toReactionMessage = async (client, cache, event, base, id, target) => {
487
647
  const type = getAssociatedMessageType(event.message);
488
648
  if (type && isTapbackRemoval(type)) {
489
649
  return [];
@@ -495,41 +655,89 @@ var toReactionMessage = (event, base, id, target) => {
495
655
  if (!emoji) {
496
656
  return [];
497
657
  }
498
- const normalizedTarget = target.replace(PART_PREFIX, "");
658
+ const { guid: strippedGuid, partIndex } = parseTapbackTarget(target);
659
+ const resolved = await resolveReactionTarget(
660
+ client,
661
+ cache,
662
+ strippedGuid,
663
+ partIndex
664
+ );
665
+ if (!resolved) {
666
+ return [];
667
+ }
499
668
  return [
500
- { ...base, id, content: asReaction({ emoji, target: normalizedTarget }) }
669
+ {
670
+ ...base,
671
+ id,
672
+ content: asReaction({ emoji, target: resolved })
673
+ }
501
674
  ];
502
675
  };
503
- var toMessages2 = async (client, event) => {
504
- const base = baseMessage(event);
676
+ var toMessages2 = async (client, cache, event) => {
677
+ const base = baseShape(event.message, event.chatGuid, event.timestamp);
505
678
  const messageGuidStr = event.message.guid;
506
679
  const assoc = event.message.associatedMessageGuid;
507
680
  if (assoc) {
508
- return toReactionMessage(event, base, messageGuidStr, assoc);
681
+ return toReactionMessage(client, cache, event, base, messageGuidStr, assoc);
509
682
  }
510
683
  if (getBalloonBundleId(event.message) === URL_BALLOON_BUNDLE_ID) {
511
- return [toRichlinkMessage(event, base, messageGuidStr)];
684
+ const msg2 = toRichlinkMessage(event, base, messageGuidStr);
685
+ cacheMessage(cache, msg2);
686
+ return [msg2];
512
687
  }
513
- if (event.message.attachments.length > 0) {
514
- return Promise.all(
515
- event.message.attachments.map(async (info) => ({
516
- ...base,
517
- id: `${messageGuidStr}:${info.guid}`,
518
- content: isVCardAttachment2(info.mimeType, info.fileName) ? await toVCardContent2(client, info) : toAttachmentContent2(client, info)
519
- }))
688
+ if (event.message.attachments.length === 1) {
689
+ const info = event.message.attachments[0];
690
+ if (!info) {
691
+ throw new Error("Unreachable: attachments.length === 1 but no element");
692
+ }
693
+ const msg2 = await buildAttachmentMessage(
694
+ client,
695
+ base,
696
+ info,
697
+ messageGuidStr,
698
+ 0
520
699
  );
700
+ cacheMessage(cache, msg2);
701
+ return [msg2];
521
702
  }
522
- const text = event.message.text;
523
- return [
524
- {
703
+ if (event.message.attachments.length > 1) {
704
+ const items = [];
705
+ for (let i = 0; i < event.message.attachments.length; i++) {
706
+ const info = event.message.attachments[i];
707
+ if (!info) {
708
+ continue;
709
+ }
710
+ items.push(
711
+ await buildAttachmentMessage(
712
+ client,
713
+ base,
714
+ info,
715
+ formatChildId(i, messageGuidStr),
716
+ i,
717
+ messageGuidStr
718
+ )
719
+ );
720
+ }
721
+ const parent = {
525
722
  ...base,
526
723
  id: messageGuidStr,
527
- content: text ? asText(text) : asCustom(event.message)
528
- }
529
- ];
724
+ content: asGroup({ items })
725
+ };
726
+ cacheMessage(cache, parent);
727
+ return [parent];
728
+ }
729
+ const text = event.message.text;
730
+ const msg = {
731
+ ...base,
732
+ id: messageGuidStr,
733
+ content: text ? asText(text) : asCustom(event.message)
734
+ };
735
+ cacheMessage(cache, msg);
736
+ return [msg];
530
737
  };
531
738
  var clientStream = (client) => {
532
739
  const sub = client.messages.subscribe("message.received");
740
+ const cache = getMessageCache(client);
533
741
  return stream((emit, end) => {
534
742
  const pump = (async () => {
535
743
  try {
@@ -537,7 +745,7 @@ var clientStream = (client) => {
537
745
  if (event.message.isFromMe) {
538
746
  continue;
539
747
  }
540
- for (const message of await toMessages2(client, event)) {
748
+ for (const message of await toMessages2(client, cache, event)) {
541
749
  await emit(message);
542
750
  }
543
751
  }
@@ -581,12 +789,7 @@ var stopTyping = async (clients, spaceId) => {
581
789
  }
582
790
  await remote.chats.stopTyping(chatGuid(spaceId));
583
791
  };
584
- var send2 = async (clients, spaceId, content) => {
585
- const remote = clients[0];
586
- if (!remote) {
587
- throw new Error("No remote iMessage client available");
588
- }
589
- const chat = chatGuid(spaceId);
792
+ var sendSingle = async (remote, chat, content) => {
590
793
  switch (content.type) {
591
794
  case "text":
592
795
  return toSendResult(await remote.messages.send(chat, content.text));
@@ -601,9 +804,7 @@ var send2 = async (clients, spaceId, content) => {
601
804
  mimeType: content.mimeType
602
805
  });
603
806
  return toSendResult(
604
- await remote.messages.send(chat, "", {
605
- attachment: attachment.guid
606
- })
807
+ await remote.messages.send(chat, "", { attachment: attachment.guid })
607
808
  );
608
809
  }
609
810
  case "contact": {
@@ -631,6 +832,34 @@ var send2 = async (clients, spaceId, content) => {
631
832
  throw unsupportedContent(content.type);
632
833
  }
633
834
  };
835
+ var send2 = async (clients, spaceId, content) => {
836
+ const remote = clients[0];
837
+ if (!remote) {
838
+ throw new Error("No remote iMessage client available");
839
+ }
840
+ const chat = chatGuid(spaceId);
841
+ if (content.type === "group") {
842
+ for (const sub of content.items) {
843
+ const itemType = sub.content.type;
844
+ if (!GROUP_ITEM_ALLOWED.has(itemType)) {
845
+ throw unsupportedContent(
846
+ "group",
847
+ `"${itemType}" items are not supported inside a group`
848
+ );
849
+ }
850
+ }
851
+ const groupMembers = [];
852
+ for (const sub of content.items) {
853
+ groupMembers.push(await sendSingle(remote, chat, sub.content));
854
+ }
855
+ const first = groupMembers[0];
856
+ if (!first) {
857
+ throw new Error("Empty group");
858
+ }
859
+ return { ...first, groupMembers };
860
+ }
861
+ return sendSingle(remote, chat, content);
862
+ };
634
863
  var replyToMessage = async (clients, spaceId, msgId, content) => {
635
864
  const remote = clients[0];
636
865
  if (!remote) {
@@ -709,18 +938,56 @@ var editMessage = async (clients, spaceId, msgId, content) => {
709
938
  content.text
710
939
  );
711
940
  };
712
- var reactToMessage = async (clients, spaceId, msgId, reaction) => {
941
+ var reactToMessage = async (clients, spaceId, target, reaction) => {
713
942
  const remote = clients[0];
714
943
  if (!remote) {
715
944
  return;
716
945
  }
717
946
  const chat = chatGuid(spaceId);
718
- const msg = messageGuid(msgId);
947
+ const parentGuid = target.parentId ?? target.id;
948
+ const guid = messageGuid(parentGuid);
949
+ const opts = typeof target.partIndex === "number" ? { partIndex: target.partIndex } : void 0;
719
950
  const native = EMOJI_TO_TAPBACK[reaction];
720
951
  if (native) {
721
- await remote.messages.react(chat, msg, native);
952
+ await remote.messages.react(chat, guid, native, opts);
722
953
  } else {
723
- await remote.messages.reactEmoji(chat, msg, reaction);
954
+ await remote.messages.reactEmoji(chat, guid, reaction, opts);
955
+ }
956
+ };
957
+ var getMessage2 = async (clients, spaceId, msgId) => {
958
+ const remote = clients[0];
959
+ if (!remote) {
960
+ return;
961
+ }
962
+ const cache = getMessageCache(remote);
963
+ const cached = cache.get(msgId);
964
+ if (cached) {
965
+ return cached;
966
+ }
967
+ const childRef = parseChildId(msgId);
968
+ if (childRef) {
969
+ try {
970
+ const fetched = await remote.messages.get(
971
+ messageGuid(childRef.parentGuid)
972
+ );
973
+ const parent = await rebuildFromAppleMessage(remote, fetched, spaceId);
974
+ cacheMessage(cache, parent);
975
+ if (parent.content.type !== "group") {
976
+ return;
977
+ }
978
+ const items = parent.content.items;
979
+ return items[childRef.partIndex];
980
+ } catch {
981
+ return;
982
+ }
983
+ }
984
+ try {
985
+ const fetched = await remote.messages.get(messageGuid(msgId));
986
+ const rebuilt = await rebuildFromAppleMessage(remote, fetched, spaceId);
987
+ cacheMessage(cache, rebuilt);
988
+ return rebuilt;
989
+ } catch {
990
+ return;
724
991
  }
725
992
  };
726
993
 
@@ -741,6 +1008,10 @@ var spaceSchema = z.object({
741
1008
  id: z.string(),
742
1009
  type: z.enum(["dm", "group"])
743
1010
  });
1011
+ var messageSchema = z.object({
1012
+ partIndex: z.number().int().nonnegative().optional(),
1013
+ parentId: z.string().optional()
1014
+ });
744
1015
 
745
1016
  // src/providers/imessage/index.ts
746
1017
  var imessage = definePlatform("iMessage", {
@@ -776,6 +1047,9 @@ var imessage = definePlatform("iMessage", {
776
1047
  return { id: chat.guid, type: "group" };
777
1048
  }
778
1049
  },
1050
+ message: {
1051
+ schema: messageSchema
1052
+ },
779
1053
  lifecycle: {
780
1054
  createClient: async ({
781
1055
  config,
@@ -829,11 +1103,16 @@ var imessage = definePlatform("iMessage", {
829
1103
  }
830
1104
  await stopTyping(client, space.id);
831
1105
  },
832
- reactToMessage: async ({ space, messageId, reaction, client }) => {
1106
+ reactToMessage: async ({ space, target, reaction, client }) => {
833
1107
  if (isLocal(client)) {
834
1108
  throw UnsupportedError.action("react", "iMessage (local mode)");
835
1109
  }
836
- await reactToMessage(client, space.id, messageId, reaction);
1110
+ await reactToMessage(
1111
+ client,
1112
+ space.id,
1113
+ target,
1114
+ reaction
1115
+ );
837
1116
  },
838
1117
  replyToMessage: async ({ space, messageId, content, client }) => {
839
1118
  if (isLocal(client)) {
@@ -846,6 +1125,12 @@ var imessage = definePlatform("iMessage", {
846
1125
  throw UnsupportedError.action("edit", "iMessage (local mode)");
847
1126
  }
848
1127
  await editMessage(client, space.id, messageId, content);
1128
+ },
1129
+ getMessage: async ({ space, messageId, client }) => {
1130
+ if (isLocal(client)) {
1131
+ return getMessage(client, messageId);
1132
+ }
1133
+ return getMessage2(client, space.id, messageId);
849
1134
  }
850
1135
  }
851
1136
  });
@@ -1,25 +1,125 @@
1
- import { d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-B8g0pvfg.js';
2
- import * as node_readline from 'node:readline';
1
+ import { d as Platform, c as PlatformDef, P as ProviderMessage, M as Message } from '../../types-D5KhSXLy.js';
3
2
  import z__default from 'zod';
4
3
  import 'hotscript';
5
4
 
6
- declare const terminal: Platform<PlatformDef<"terminal", z__default.ZodObject<{}, z__default.core.$strip>, z__default.ZodType<object, unknown, z__default.core.$ZodTypeInternals<object, unknown>> | undefined, z__default.ZodType<object, unknown, z__default.core.$ZodTypeInternals<object, unknown>> | undefined, z__default.ZodType<object, unknown, z__default.core.$ZodTypeInternals<object, unknown>> | undefined, node_readline.Interface, {
5
+ declare const terminal: Platform<PlatformDef<"terminal", z__default.ZodObject<{
6
+ commands: z__default.ZodOptional<z__default.ZodArray<z__default.ZodObject<{
7
+ name: z__default.ZodString;
8
+ description: z__default.ZodOptional<z__default.ZodString>;
9
+ }, z__default.core.$strip>>>;
10
+ }, z__default.core.$strip>, z__default.ZodType<object, unknown, z__default.core.$ZodTypeInternals<object, unknown>> | undefined, z__default.ZodType<object, unknown, z__default.core.$ZodTypeInternals<object, unknown>> | undefined, z__default.ZodObject<{
11
+ id: z__default.ZodOptional<z__default.ZodString>;
12
+ }, z__default.core.$strip>, unknown, {
7
13
  id: string;
8
14
  }, {
9
15
  id: string;
10
- }, undefined, ProviderMessage<{
16
+ }, z__default.ZodObject<{
17
+ replyTo: z__default.ZodOptional<z__default.ZodObject<{
18
+ messageId: z__default.ZodString;
19
+ }, z__default.core.$strip>>;
20
+ }, z__default.core.$strip>, ProviderMessage<{
11
21
  id: string;
12
22
  }, {
13
23
  id: string;
14
- }, Record<never, never>>, {
15
- messages({ client }: {
16
- client: node_readline.Interface;
17
- config: Record<string, never>;
24
+ }, {
25
+ replyTo?: {
26
+ messageId: string;
27
+ } | undefined;
28
+ }>, {
29
+ messages(ctx: {
30
+ client: unknown;
31
+ config: {
32
+ commands?: {
33
+ name: string;
34
+ description?: string | undefined;
35
+ }[] | undefined;
36
+ };
18
37
  }): AsyncGenerator<{
19
- id: `${string}-${string}-${string}-${string}-${string}`;
38
+ replyTo?: {
39
+ messageId: string;
40
+ } | undefined;
41
+ id: string;
20
42
  content: {
21
43
  type: "text";
22
44
  text: string;
45
+ } | {
46
+ type: "custom";
47
+ raw: unknown;
48
+ } | {
49
+ type: "attachment";
50
+ name: string;
51
+ mimeType: string;
52
+ read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
53
+ stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
54
+ size?: number | undefined;
55
+ } | {
56
+ type: "contact";
57
+ user?: {
58
+ __platform: string;
59
+ id: string;
60
+ } | undefined;
61
+ name?: {
62
+ formatted?: string | undefined;
63
+ first?: string | undefined;
64
+ last?: string | undefined;
65
+ middle?: string | undefined;
66
+ prefix?: string | undefined;
67
+ suffix?: string | undefined;
68
+ } | undefined;
69
+ phones?: {
70
+ value: string;
71
+ type?: "mobile" | "home" | "work" | "other" | undefined;
72
+ }[] | undefined;
73
+ emails?: {
74
+ value: string;
75
+ type?: "home" | "work" | "other" | undefined;
76
+ }[] | undefined;
77
+ addresses?: {
78
+ street?: string | undefined;
79
+ city?: string | undefined;
80
+ region?: string | undefined;
81
+ postalCode?: string | undefined;
82
+ country?: string | undefined;
83
+ type?: "home" | "work" | "other" | undefined;
84
+ }[] | undefined;
85
+ org?: {
86
+ name?: string | undefined;
87
+ title?: string | undefined;
88
+ department?: string | undefined;
89
+ } | undefined;
90
+ urls?: string[] | undefined;
91
+ birthday?: string | undefined;
92
+ note?: string | undefined;
93
+ photo?: {
94
+ mimeType: string;
95
+ read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
96
+ } | undefined;
97
+ raw?: unknown;
98
+ } | {
99
+ type: "voice";
100
+ mimeType: string;
101
+ read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
102
+ stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
103
+ name?: string | undefined;
104
+ duration?: number | undefined;
105
+ size?: number | undefined;
106
+ } | {
107
+ type: "richlink";
108
+ url: string;
109
+ title: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodOptional<z__default.ZodString>>>;
110
+ summary: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodOptional<z__default.ZodString>>>;
111
+ cover: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodOptional<z__default.ZodObject<{
112
+ mimeType: z__default.ZodOptional<z__default.ZodString>;
113
+ read: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
114
+ stream: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
115
+ }, z__default.core.$strip>>>>;
116
+ } | {
117
+ type: "reaction";
118
+ emoji: string;
119
+ target: Message;
120
+ } | {
121
+ type: "group";
122
+ items: Message[];
23
123
  };
24
124
  sender: {
25
125
  id: string;