spectrum-ts 1.1.1 → 1.1.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/dist/{chunk-7D6FHYKT.js → chunk-5GQ2OMFY.js} +49 -71
- package/dist/{chunk-PXX7ISZ6.js → chunk-FF2R4EP3.js} +82 -0
- package/dist/{chunk-7VSE6V3Q.js → chunk-QZ5DJ7VR.js} +1 -1
- package/dist/{chunk-TY3RT4OB.js → chunk-UWUPCIB4.js} +2 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +60 -27
- package/dist/providers/imessage/index.d.ts +1 -2
- package/dist/providers/imessage/index.js +154 -78
- package/dist/providers/terminal/index.d.ts +1 -1
- package/dist/providers/terminal/index.js +12 -4
- package/dist/providers/whatsapp-business/index.d.ts +1 -2
- package/dist/providers/whatsapp-business/index.js +41 -22
- package/dist/{types-BZhWdyLk.d.ts → types-GhOtIIqj.d.ts} +49 -21
- package/package.json +2 -2
- package/dist/stream-B55k7W8-.d.ts +0 -8
|
@@ -672,29 +672,36 @@ var extractExtras = (raw, definition) => {
|
|
|
672
672
|
const extra = Object.fromEntries(entries);
|
|
673
673
|
return definition.message?.schema ? definition.message.schema.parse(extra) : extra;
|
|
674
674
|
};
|
|
675
|
-
function wrapProviderMessage(raw, ctx) {
|
|
676
|
-
const wrappedContent = wrapNestedContent(raw.content, ctx);
|
|
677
|
-
|
|
675
|
+
function wrapProviderMessage(raw, ctx, direction) {
|
|
676
|
+
const wrappedContent = wrapNestedContent(raw.content, ctx, direction);
|
|
677
|
+
const base = {
|
|
678
678
|
id: raw.id,
|
|
679
679
|
content: wrappedContent,
|
|
680
|
-
sender: raw.sender,
|
|
681
680
|
timestamp: raw.timestamp ?? /* @__PURE__ */ new Date(),
|
|
682
681
|
extras: extractExtras(raw, ctx.definition),
|
|
683
682
|
spaceRef: ctx.spaceRef,
|
|
684
683
|
space: ctx.space,
|
|
685
684
|
definition: ctx.definition,
|
|
686
685
|
client: ctx.client,
|
|
687
|
-
config: ctx.config
|
|
688
|
-
|
|
689
|
-
|
|
686
|
+
config: ctx.config
|
|
687
|
+
};
|
|
688
|
+
if (direction === "inbound") {
|
|
689
|
+
if (!raw.sender) {
|
|
690
|
+
throw new Error(
|
|
691
|
+
`Inbound provider message missing sender (platform "${ctx.definition.name}", id "${raw.id}")`
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
return buildMessage({ ...base, sender: raw.sender, direction: "inbound" });
|
|
695
|
+
}
|
|
696
|
+
return buildMessage({ ...base, sender: raw.sender, direction: "outbound" });
|
|
690
697
|
}
|
|
691
|
-
var wrapNestedContent = (content, ctx) => {
|
|
698
|
+
var wrapNestedContent = (content, ctx, direction) => {
|
|
692
699
|
if (content.type === "reaction") {
|
|
693
700
|
const target = content.target;
|
|
694
701
|
if (isRawProviderRecord(target)) {
|
|
695
702
|
return {
|
|
696
703
|
...content,
|
|
697
|
-
target: wrapProviderMessage(target, ctx)
|
|
704
|
+
target: wrapProviderMessage(target, ctx, "inbound")
|
|
698
705
|
};
|
|
699
706
|
}
|
|
700
707
|
return content;
|
|
@@ -702,7 +709,10 @@ var wrapNestedContent = (content, ctx) => {
|
|
|
702
709
|
if (content.type === "group") {
|
|
703
710
|
const items = content.items.map((item) => {
|
|
704
711
|
const raw = item;
|
|
705
|
-
|
|
712
|
+
if (!isRawProviderRecord(raw)) {
|
|
713
|
+
return item;
|
|
714
|
+
}
|
|
715
|
+
return direction === "inbound" ? wrapProviderMessage(raw, ctx, "inbound") : wrapProviderMessage(raw, ctx, "outbound");
|
|
706
716
|
});
|
|
707
717
|
return { ...content, items };
|
|
708
718
|
}
|
|
@@ -739,9 +749,9 @@ function buildSpace(params) {
|
|
|
739
749
|
}
|
|
740
750
|
}
|
|
741
751
|
async function dispatchSend(item) {
|
|
742
|
-
let
|
|
752
|
+
let raw;
|
|
743
753
|
try {
|
|
744
|
-
|
|
754
|
+
raw = await definition.actions.send({
|
|
745
755
|
...typingCtx,
|
|
746
756
|
content: item
|
|
747
757
|
});
|
|
@@ -752,46 +762,16 @@ function buildSpace(params) {
|
|
|
752
762
|
}
|
|
753
763
|
throw err;
|
|
754
764
|
}
|
|
755
|
-
if (!
|
|
765
|
+
if (!raw?.id) {
|
|
756
766
|
throw new Error(
|
|
757
767
|
`Platform "${definition.name}" send did not return a message id`
|
|
758
768
|
);
|
|
759
769
|
}
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
return stub;
|
|
766
|
-
}
|
|
767
|
-
return buildMessage({
|
|
768
|
-
id: member.id,
|
|
769
|
-
content: stub.content,
|
|
770
|
-
sender: member.sender,
|
|
771
|
-
timestamp: member.timestamp ?? /* @__PURE__ */ new Date(),
|
|
772
|
-
extras: {},
|
|
773
|
-
spaceRef,
|
|
774
|
-
space,
|
|
775
|
-
definition,
|
|
776
|
-
client,
|
|
777
|
-
config,
|
|
778
|
-
direction: "outbound"
|
|
779
|
-
});
|
|
780
|
-
})
|
|
781
|
-
} : item;
|
|
782
|
-
return buildMessage({
|
|
783
|
-
id: sendResult.id,
|
|
784
|
-
content: outboundContent,
|
|
785
|
-
sender: sendResult.sender,
|
|
786
|
-
timestamp: sendResult.timestamp ?? /* @__PURE__ */ new Date(),
|
|
787
|
-
extras: {},
|
|
788
|
-
spaceRef,
|
|
789
|
-
space,
|
|
790
|
-
definition,
|
|
791
|
-
client,
|
|
792
|
-
config,
|
|
793
|
-
direction: "outbound"
|
|
794
|
-
});
|
|
770
|
+
return wrapProviderMessage(
|
|
771
|
+
raw,
|
|
772
|
+
{ client, config, definition, space, spaceRef },
|
|
773
|
+
"outbound"
|
|
774
|
+
);
|
|
795
775
|
}
|
|
796
776
|
async function sendImpl(...content) {
|
|
797
777
|
const resolved = await resolveContents(content);
|
|
@@ -837,13 +817,11 @@ function buildSpace(params) {
|
|
|
837
817
|
if (!raw) {
|
|
838
818
|
return;
|
|
839
819
|
}
|
|
840
|
-
return wrapProviderMessage(
|
|
841
|
-
|
|
842
|
-
config,
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
spaceRef
|
|
846
|
-
});
|
|
820
|
+
return wrapProviderMessage(
|
|
821
|
+
raw,
|
|
822
|
+
{ client, config, definition, space, spaceRef },
|
|
823
|
+
"inbound"
|
|
824
|
+
);
|
|
847
825
|
}
|
|
848
826
|
space = {
|
|
849
827
|
...extras,
|
|
@@ -912,9 +890,9 @@ function buildMessage(params) {
|
|
|
912
890
|
return self;
|
|
913
891
|
};
|
|
914
892
|
const dispatchReplyItem = async (item, target, replyToMessage) => {
|
|
915
|
-
let
|
|
893
|
+
let raw;
|
|
916
894
|
try {
|
|
917
|
-
|
|
895
|
+
raw = await replyToMessage({
|
|
918
896
|
space: spaceRef,
|
|
919
897
|
messageId: params.id,
|
|
920
898
|
target,
|
|
@@ -929,24 +907,16 @@ function buildMessage(params) {
|
|
|
929
907
|
}
|
|
930
908
|
throw err;
|
|
931
909
|
}
|
|
932
|
-
if (!
|
|
910
|
+
if (!raw?.id) {
|
|
933
911
|
throw new Error(
|
|
934
912
|
`Platform "${definition.name}" reply did not return a message id`
|
|
935
913
|
);
|
|
936
914
|
}
|
|
937
|
-
return
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
extras: {},
|
|
943
|
-
spaceRef,
|
|
944
|
-
space,
|
|
945
|
-
definition,
|
|
946
|
-
client,
|
|
947
|
-
config,
|
|
948
|
-
direction: "outbound"
|
|
949
|
-
});
|
|
915
|
+
return wrapProviderMessage(
|
|
916
|
+
raw,
|
|
917
|
+
{ client, config, definition, space, spaceRef },
|
|
918
|
+
"outbound"
|
|
919
|
+
);
|
|
950
920
|
};
|
|
951
921
|
async function reply(...content) {
|
|
952
922
|
const replyToMessage = definition.actions.replyToMessage;
|
|
@@ -1146,6 +1116,14 @@ function createPlatformInstance(def, runtime) {
|
|
|
1146
1116
|
});
|
|
1147
1117
|
}
|
|
1148
1118
|
}
|
|
1119
|
+
let messagesIterable;
|
|
1120
|
+
Object.defineProperty(base, "messages", {
|
|
1121
|
+
enumerable: true,
|
|
1122
|
+
get() {
|
|
1123
|
+
messagesIterable ??= runtime.subscribeMessages();
|
|
1124
|
+
return messagesIterable;
|
|
1125
|
+
}
|
|
1126
|
+
});
|
|
1149
1127
|
return Object.assign(base, eventProperties);
|
|
1150
1128
|
}
|
|
1151
1129
|
function definePlatform(name, def) {
|
|
@@ -108,6 +108,87 @@ function mergeStreams(streams) {
|
|
|
108
108
|
};
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
|
+
function broadcast(source) {
|
|
112
|
+
const consumers = /* @__PURE__ */ new Set();
|
|
113
|
+
let pumping = false;
|
|
114
|
+
let terminated = false;
|
|
115
|
+
let terminalError;
|
|
116
|
+
let pumpPromise;
|
|
117
|
+
let closed = false;
|
|
118
|
+
const startPump = () => {
|
|
119
|
+
if (pumping || terminated) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
pumping = true;
|
|
123
|
+
pumpPromise = (async () => {
|
|
124
|
+
try {
|
|
125
|
+
for await (const value of source) {
|
|
126
|
+
for (const consumer of consumers) {
|
|
127
|
+
consumer.deliveries = consumer.deliveries.then(
|
|
128
|
+
() => consumer.emit(value).catch(() => {
|
|
129
|
+
})
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
terminated = true;
|
|
134
|
+
await Promise.allSettled(
|
|
135
|
+
Array.from(consumers, (consumer) => consumer.deliveries)
|
|
136
|
+
);
|
|
137
|
+
for (const consumer of consumers) {
|
|
138
|
+
consumer.end();
|
|
139
|
+
}
|
|
140
|
+
consumers.clear();
|
|
141
|
+
} catch (error) {
|
|
142
|
+
terminated = true;
|
|
143
|
+
terminalError = error;
|
|
144
|
+
for (const consumer of consumers) {
|
|
145
|
+
consumer.end(error);
|
|
146
|
+
}
|
|
147
|
+
consumers.clear();
|
|
148
|
+
}
|
|
149
|
+
})();
|
|
150
|
+
};
|
|
151
|
+
return {
|
|
152
|
+
subscribe() {
|
|
153
|
+
return stream((emit, end) => {
|
|
154
|
+
if (terminated) {
|
|
155
|
+
end(terminalError);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const consumer = {
|
|
159
|
+
emit,
|
|
160
|
+
end,
|
|
161
|
+
deliveries: Promise.resolve()
|
|
162
|
+
};
|
|
163
|
+
consumers.add(consumer);
|
|
164
|
+
startPump();
|
|
165
|
+
return () => {
|
|
166
|
+
consumers.delete(consumer);
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
},
|
|
170
|
+
async close() {
|
|
171
|
+
if (closed) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
closed = true;
|
|
175
|
+
try {
|
|
176
|
+
await source.close();
|
|
177
|
+
if (pumpPromise) {
|
|
178
|
+
await pumpPromise;
|
|
179
|
+
}
|
|
180
|
+
} finally {
|
|
181
|
+
if (!terminated) {
|
|
182
|
+
terminated = true;
|
|
183
|
+
for (const consumer of consumers) {
|
|
184
|
+
consumer.end();
|
|
185
|
+
}
|
|
186
|
+
consumers.clear();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
111
192
|
|
|
112
193
|
// src/utils/cloud.ts
|
|
113
194
|
var SPECTRUM_CLOUD_URL = `https://${process.env.SPECTRUM_CLOUD_URL ?? "spectrum.photon.codes"}`;
|
|
@@ -183,6 +264,7 @@ export {
|
|
|
183
264
|
poll,
|
|
184
265
|
stream,
|
|
185
266
|
mergeStreams,
|
|
267
|
+
broadcast,
|
|
186
268
|
SpectrumCloudError,
|
|
187
269
|
cloud
|
|
188
270
|
};
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
readSchema,
|
|
4
4
|
resolveContents,
|
|
5
5
|
streamSchema
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-5GQ2OMFY.js";
|
|
7
7
|
|
|
8
8
|
// src/content/group.ts
|
|
9
9
|
import z from "zod";
|
|
@@ -163,6 +163,7 @@ function richlink(url) {
|
|
|
163
163
|
|
|
164
164
|
export {
|
|
165
165
|
groupSchema,
|
|
166
|
+
asGroup,
|
|
166
167
|
group,
|
|
167
168
|
asRichlink,
|
|
168
169
|
richlink
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { C as ContentBuilder, U as User, M as Message, a as ContentInput, b as Content, P as ProviderMessage, c as PlatformDef, d as Platform, e as PlatformProviderConfig, S as SpectrumLike, f as CustomEventStreams, g as Space, I as InboundMessage, O as OutboundMessage } from './types-
|
|
2
|
-
export { A as AnyPlatformDef, E as EventProducer, h as
|
|
1
|
+
import { C as ContentBuilder, U as User, M as Message, a as ContentInput, b as Content, P as ProviderMessage, c as PlatformDef, d as Platform, e as PlatformProviderConfig, S as SpectrumLike, f as CustomEventStreams, g as Space, I as InboundMessage, O as OutboundMessage } from './types-GhOtIIqj.js';
|
|
2
|
+
export { A as AnyPlatformDef, B as Broadcaster, E as EventProducer, h as InboundPlatformMessage, i as ManagedStream, j as PlatformInstance, k as PlatformMessage, l as PlatformRuntime, m as PlatformSpace, n as PlatformUser, o as SchemaMessage, p as broadcast, q as mergeStreams, s as stream } from './types-GhOtIIqj.js';
|
|
3
3
|
import vCard from 'vcf';
|
|
4
4
|
import z__default from 'zod';
|
|
5
|
-
export { M as ManagedStream, m as mergeStreams, s as stream } from './stream-B55k7W8-.js';
|
|
6
5
|
import 'hotscript';
|
|
7
6
|
|
|
8
7
|
declare function attachment(input: string | Buffer, options?: {
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
group,
|
|
3
3
|
richlink
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UWUPCIB4.js";
|
|
5
5
|
import {
|
|
6
6
|
voice
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QZ5DJ7VR.js";
|
|
8
8
|
import {
|
|
9
9
|
SpectrumCloudError,
|
|
10
|
+
broadcast,
|
|
10
11
|
cloud,
|
|
11
12
|
mergeStreams,
|
|
12
13
|
option,
|
|
13
14
|
poll,
|
|
14
15
|
stream
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-FF2R4EP3.js";
|
|
16
17
|
import {
|
|
17
18
|
UnsupportedError,
|
|
18
19
|
attachment,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
text,
|
|
27
28
|
toVCard,
|
|
28
29
|
wrapProviderMessage
|
|
29
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-5GQ2OMFY.js";
|
|
30
31
|
|
|
31
32
|
// src/emoji/generated.ts
|
|
32
33
|
var GeneratedEmoji = {
|
|
@@ -1986,23 +1987,9 @@ async function Spectrum(options) {
|
|
|
1986
1987
|
} = options;
|
|
1987
1988
|
const flattenGroups = runtimeOptions?.flattenGroups ?? false;
|
|
1988
1989
|
const platformStates = /* @__PURE__ */ new Map();
|
|
1990
|
+
const messageBroadcasters = /* @__PURE__ */ new Map();
|
|
1989
1991
|
const customEventStreams = /* @__PURE__ */ new Map();
|
|
1990
1992
|
let stopped = false;
|
|
1991
|
-
for (const provider of providers) {
|
|
1992
|
-
const providerConfig = provider;
|
|
1993
|
-
const def = providerConfig.__definition;
|
|
1994
|
-
const userConfig = def.config.parse(providerConfig.config);
|
|
1995
|
-
const client = await def.lifecycle.createClient({
|
|
1996
|
-
config: userConfig,
|
|
1997
|
-
projectId,
|
|
1998
|
-
projectSecret
|
|
1999
|
-
});
|
|
2000
|
-
platformStates.set(def.name, {
|
|
2001
|
-
client,
|
|
2002
|
-
config: userConfig,
|
|
2003
|
-
definition: def
|
|
2004
|
-
});
|
|
2005
|
-
}
|
|
2006
1993
|
const adaptIterable = (iterable) => {
|
|
2007
1994
|
return stream((emit, end) => {
|
|
2008
1995
|
const iterator = iterable[Symbol.asyncIterator]();
|
|
@@ -2045,13 +2032,17 @@ async function Spectrum(options) {
|
|
|
2045
2032
|
client,
|
|
2046
2033
|
config
|
|
2047
2034
|
});
|
|
2048
|
-
const normalizedMessage = wrapProviderMessage(
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2035
|
+
const normalizedMessage = wrapProviderMessage(
|
|
2036
|
+
msg,
|
|
2037
|
+
{
|
|
2038
|
+
client,
|
|
2039
|
+
config,
|
|
2040
|
+
definition,
|
|
2041
|
+
space,
|
|
2042
|
+
spaceRef
|
|
2043
|
+
},
|
|
2044
|
+
"inbound"
|
|
2045
|
+
);
|
|
2055
2046
|
if (flattenGroups && normalizedMessage.content.type === "group") {
|
|
2056
2047
|
for (const item of normalizedMessage.content.items) {
|
|
2057
2048
|
yield [space, item];
|
|
@@ -2063,10 +2054,46 @@ async function Spectrum(options) {
|
|
|
2063
2054
|
};
|
|
2064
2055
|
return adaptIterable(bindSend());
|
|
2065
2056
|
};
|
|
2057
|
+
const getOrCreateMessageBroadcast = (state) => {
|
|
2058
|
+
if (stopped) {
|
|
2059
|
+
throw new Error(
|
|
2060
|
+
`Spectrum instance has been stopped; cannot subscribe to "${state.definition.name}" messages`
|
|
2061
|
+
);
|
|
2062
|
+
}
|
|
2063
|
+
const name = state.definition.name;
|
|
2064
|
+
let broadcaster = messageBroadcasters.get(name);
|
|
2065
|
+
if (!broadcaster) {
|
|
2066
|
+
broadcaster = broadcast(createProviderMessagesStream(state));
|
|
2067
|
+
messageBroadcasters.set(name, broadcaster);
|
|
2068
|
+
}
|
|
2069
|
+
return broadcaster;
|
|
2070
|
+
};
|
|
2071
|
+
for (const provider of providers) {
|
|
2072
|
+
const providerConfig = provider;
|
|
2073
|
+
const def = providerConfig.__definition;
|
|
2074
|
+
const userConfig = def.config.parse(providerConfig.config);
|
|
2075
|
+
const client = await def.lifecycle.createClient({
|
|
2076
|
+
config: userConfig,
|
|
2077
|
+
projectId,
|
|
2078
|
+
projectSecret
|
|
2079
|
+
});
|
|
2080
|
+
const state = {
|
|
2081
|
+
client,
|
|
2082
|
+
config: userConfig,
|
|
2083
|
+
definition: def
|
|
2084
|
+
};
|
|
2085
|
+
platformStates.set(def.name, {
|
|
2086
|
+
...state,
|
|
2087
|
+
subscribeMessages: () => getOrCreateMessageBroadcast(state).subscribe()
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2066
2090
|
const createMessagesStream = () => {
|
|
2067
2091
|
return stream((emit, end) => {
|
|
2068
2092
|
const merged = mergeStreams(
|
|
2069
|
-
Array.from(
|
|
2093
|
+
Array.from(
|
|
2094
|
+
platformStates.values(),
|
|
2095
|
+
(runtime) => runtime.subscribeMessages()
|
|
2096
|
+
)
|
|
2070
2097
|
);
|
|
2071
2098
|
const pump = (async () => {
|
|
2072
2099
|
try {
|
|
@@ -2130,6 +2157,10 @@ async function Spectrum(options) {
|
|
|
2130
2157
|
...Array.from(
|
|
2131
2158
|
customEventStreams.values(),
|
|
2132
2159
|
(eventStream) => eventStream.close()
|
|
2160
|
+
),
|
|
2161
|
+
...Array.from(
|
|
2162
|
+
messageBroadcasters.values(),
|
|
2163
|
+
(broadcaster) => broadcaster.close()
|
|
2133
2164
|
)
|
|
2134
2165
|
];
|
|
2135
2166
|
process.off("SIGINT", handleSignal);
|
|
@@ -2143,6 +2174,7 @@ async function Spectrum(options) {
|
|
|
2143
2174
|
);
|
|
2144
2175
|
await Promise.allSettled(clientShutdowns);
|
|
2145
2176
|
customEventStreams.clear();
|
|
2177
|
+
messageBroadcasters.clear();
|
|
2146
2178
|
platformStates.clear();
|
|
2147
2179
|
};
|
|
2148
2180
|
const handleSignal = () => {
|
|
@@ -2200,6 +2232,7 @@ export {
|
|
|
2200
2232
|
SpectrumCloudError,
|
|
2201
2233
|
UnsupportedError,
|
|
2202
2234
|
attachment,
|
|
2235
|
+
broadcast,
|
|
2203
2236
|
cloud,
|
|
2204
2237
|
contact,
|
|
2205
2238
|
custom,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-BZhWdyLk.js';
|
|
1
|
+
import { o as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage, i as ManagedStream } from '../../types-GhOtIIqj.js';
|
|
3
2
|
import * as zod_v4_core from 'zod/v4/core';
|
|
4
3
|
import * as z from 'zod';
|
|
5
4
|
import z__default from 'zod';
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
+
asGroup,
|
|
2
3
|
asRichlink,
|
|
3
4
|
groupSchema
|
|
4
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-UWUPCIB4.js";
|
|
5
6
|
import {
|
|
6
7
|
asPoll,
|
|
7
8
|
asPollOption,
|
|
8
9
|
cloud,
|
|
9
10
|
mergeStreams,
|
|
10
11
|
stream
|
|
11
|
-
} from "../../chunk-
|
|
12
|
+
} from "../../chunk-FF2R4EP3.js";
|
|
12
13
|
import {
|
|
13
14
|
UnsupportedError,
|
|
14
15
|
asAttachment,
|
|
@@ -19,7 +20,7 @@ import {
|
|
|
19
20
|
fromVCard,
|
|
20
21
|
reactionSchema,
|
|
21
22
|
toVCard
|
|
22
|
-
} from "../../chunk-
|
|
23
|
+
} from "../../chunk-5GQ2OMFY.js";
|
|
23
24
|
|
|
24
25
|
// src/providers/imessage/index.ts
|
|
25
26
|
import { createClient as createClient2, directChat } from "@photon-ai/advanced-imessage";
|
|
@@ -232,8 +233,10 @@ var unsupportedRemoteContent = (type, detail) => UnsupportedError.content(type,
|
|
|
232
233
|
var unsupportedLocalContent = (type) => UnsupportedError.content(type, LOCAL_IMESSAGE_PLATFORM);
|
|
233
234
|
|
|
234
235
|
// src/providers/imessage/local/send.ts
|
|
235
|
-
var
|
|
236
|
+
var synthRecord = (spaceId, content) => ({
|
|
236
237
|
id: crypto.randomUUID(),
|
|
238
|
+
content,
|
|
239
|
+
space: { id: spaceId },
|
|
237
240
|
timestamp: /* @__PURE__ */ new Date()
|
|
238
241
|
});
|
|
239
242
|
var sendTempFile = async (client, spaceId, name, data) => {
|
|
@@ -252,10 +255,10 @@ var send = async (client, spaceId, content) => {
|
|
|
252
255
|
switch (content.type) {
|
|
253
256
|
case "text":
|
|
254
257
|
await client.send({ to: spaceId, text: content.text });
|
|
255
|
-
return
|
|
258
|
+
return synthRecord(spaceId, content);
|
|
256
259
|
case "attachment":
|
|
257
260
|
await sendTempFile(client, spaceId, content.name, await content.read());
|
|
258
|
-
return
|
|
261
|
+
return synthRecord(spaceId, content);
|
|
259
262
|
case "contact": {
|
|
260
263
|
const vcf = await toVCard(content);
|
|
261
264
|
await sendTempFile(
|
|
@@ -264,7 +267,7 @@ var send = async (client, spaceId, content) => {
|
|
|
264
267
|
vcardFileName(content),
|
|
265
268
|
Buffer.from(vcf, "utf8")
|
|
266
269
|
);
|
|
267
|
-
return
|
|
270
|
+
return synthRecord(spaceId, content);
|
|
268
271
|
}
|
|
269
272
|
case "poll":
|
|
270
273
|
throw unsupportedLocalContent("poll");
|
|
@@ -927,20 +930,12 @@ var ensureM4a = async (buffer, mimeType) => {
|
|
|
927
930
|
|
|
928
931
|
// src/providers/imessage/remote/send.ts
|
|
929
932
|
var GROUP_ITEM_ALLOWED = /* @__PURE__ */ new Set([
|
|
933
|
+
"text",
|
|
930
934
|
"attachment",
|
|
931
935
|
"contact",
|
|
932
936
|
"voice"
|
|
933
937
|
]);
|
|
934
|
-
var
|
|
935
|
-
cause;
|
|
936
|
-
groupMembers;
|
|
937
|
-
constructor(groupMembers, cause) {
|
|
938
|
-
super("iMessage group send failed after one or more items were sent");
|
|
939
|
-
this.name = "PartialGroupSendError";
|
|
940
|
-
this.cause = cause;
|
|
941
|
-
this.groupMembers = groupMembers;
|
|
942
|
-
}
|
|
943
|
-
};
|
|
938
|
+
var MAX_GROUP_TEXT_ITEMS = 1;
|
|
944
939
|
var toDate = (value) => {
|
|
945
940
|
if (value instanceof Date) {
|
|
946
941
|
return value;
|
|
@@ -951,15 +946,19 @@ var toDate = (value) => {
|
|
|
951
946
|
}
|
|
952
947
|
};
|
|
953
948
|
var receiptTimestamp = (receipt) => toDate(receipt.timestamp) ?? toDate(receipt.date) ?? toDate(receipt.dateCreated) ?? /* @__PURE__ */ new Date();
|
|
954
|
-
var
|
|
949
|
+
var receiptGuid = (receipt) => {
|
|
955
950
|
if (typeof receipt.guid !== "string" || receipt.guid.length === 0) {
|
|
956
951
|
throw new Error("iMessage send receipt is missing a message guid");
|
|
957
952
|
}
|
|
958
|
-
return
|
|
959
|
-
id: receipt.guid,
|
|
960
|
-
timestamp: receiptTimestamp(receipt)
|
|
961
|
-
};
|
|
953
|
+
return receipt.guid;
|
|
962
954
|
};
|
|
955
|
+
var outboundRecord = (spaceId, id, content, timestamp, extras) => ({
|
|
956
|
+
id,
|
|
957
|
+
content,
|
|
958
|
+
space: { id: spaceId },
|
|
959
|
+
timestamp,
|
|
960
|
+
...extras
|
|
961
|
+
});
|
|
963
962
|
var withReply = (options, replyTo) => replyTo ? { ...options, replyTo } : options;
|
|
964
963
|
var replyOptions = (replyTo) => replyTo ? { replyTo } : void 0;
|
|
965
964
|
var sendVCardAttachment = (remote, name, vcf) => remote.attachments.upload({
|
|
@@ -969,8 +968,9 @@ var sendVCardAttachment = (remote, name, vcf) => remote.attachments.upload({
|
|
|
969
968
|
});
|
|
970
969
|
var sendContactAttachment = async (remote, content) => {
|
|
971
970
|
const vcf = await toVCard(content);
|
|
972
|
-
const
|
|
973
|
-
|
|
971
|
+
const name = vcardFileName(content);
|
|
972
|
+
const upload = await sendVCardAttachment(remote, name, vcf);
|
|
973
|
+
return { guid: upload.guid, name };
|
|
974
974
|
};
|
|
975
975
|
var uploadAttachment = async (remote, content) => {
|
|
976
976
|
const attachment = await remote.attachments.upload({
|
|
@@ -978,53 +978,86 @@ var uploadAttachment = async (remote, content) => {
|
|
|
978
978
|
fileName: content.name,
|
|
979
979
|
mimeType: content.mimeType
|
|
980
980
|
});
|
|
981
|
-
return attachment.guid;
|
|
981
|
+
return { guid: attachment.guid, name: content.name };
|
|
982
982
|
};
|
|
983
983
|
var uploadVoice = async (remote, content) => {
|
|
984
984
|
const { buffer } = await ensureM4a(await content.read(), content.mimeType);
|
|
985
|
+
const name = content.name ?? "voice.m4a";
|
|
985
986
|
const attachment = await remote.attachments.upload({
|
|
986
987
|
data: buffer,
|
|
987
|
-
fileName:
|
|
988
|
+
fileName: name,
|
|
988
989
|
mimeType: "audio/x-m4a"
|
|
989
990
|
});
|
|
990
|
-
return attachment.guid;
|
|
991
|
+
return { guid: attachment.guid, name };
|
|
991
992
|
};
|
|
992
|
-
var sendContent = async (remote, chat, content, replyTo) => {
|
|
993
|
+
var sendContent = async (remote, spaceId, chat, content, replyTo) => {
|
|
993
994
|
switch (content.type) {
|
|
994
|
-
case "text":
|
|
995
|
-
|
|
996
|
-
|
|
995
|
+
case "text": {
|
|
996
|
+
const receipt = await remote.messages.send(
|
|
997
|
+
chat,
|
|
998
|
+
content.text,
|
|
999
|
+
withReply({}, replyTo)
|
|
997
1000
|
);
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
withReply({ richLink: true }, replyTo)
|
|
1004
|
-
)
|
|
1001
|
+
return outboundRecord(
|
|
1002
|
+
spaceId,
|
|
1003
|
+
receiptGuid(receipt),
|
|
1004
|
+
content,
|
|
1005
|
+
receiptTimestamp(receipt)
|
|
1005
1006
|
);
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
})
|
|
1007
|
+
}
|
|
1008
|
+
case "richlink": {
|
|
1009
|
+
const receipt = await remote.messages.send(
|
|
1010
|
+
chat,
|
|
1011
|
+
content.url,
|
|
1012
|
+
withReply({ richLink: true }, replyTo)
|
|
1012
1013
|
);
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
})
|
|
1014
|
+
return outboundRecord(
|
|
1015
|
+
spaceId,
|
|
1016
|
+
receiptGuid(receipt),
|
|
1017
|
+
content,
|
|
1018
|
+
receiptTimestamp(receipt)
|
|
1019
1019
|
);
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1020
|
+
}
|
|
1021
|
+
case "attachment": {
|
|
1022
|
+
const { guid } = await uploadAttachment(remote, content);
|
|
1023
|
+
const receipt = await remote.messages.send(chat, "", {
|
|
1024
|
+
attachment: guid,
|
|
1025
|
+
...replyOptions(replyTo)
|
|
1026
|
+
});
|
|
1027
|
+
return outboundRecord(
|
|
1028
|
+
spaceId,
|
|
1029
|
+
receiptGuid(receipt),
|
|
1030
|
+
content,
|
|
1031
|
+
receiptTimestamp(receipt)
|
|
1027
1032
|
);
|
|
1033
|
+
}
|
|
1034
|
+
case "contact": {
|
|
1035
|
+
const { guid } = await sendContactAttachment(remote, content);
|
|
1036
|
+
const receipt = await remote.messages.send(chat, "", {
|
|
1037
|
+
attachment: guid,
|
|
1038
|
+
...replyOptions(replyTo)
|
|
1039
|
+
});
|
|
1040
|
+
return outboundRecord(
|
|
1041
|
+
spaceId,
|
|
1042
|
+
receiptGuid(receipt),
|
|
1043
|
+
content,
|
|
1044
|
+
receiptTimestamp(receipt)
|
|
1045
|
+
);
|
|
1046
|
+
}
|
|
1047
|
+
case "voice": {
|
|
1048
|
+
const { guid } = await uploadVoice(remote, content);
|
|
1049
|
+
const receipt = await remote.messages.send(chat, "", {
|
|
1050
|
+
attachment: guid,
|
|
1051
|
+
audioMessage: true,
|
|
1052
|
+
...replyOptions(replyTo)
|
|
1053
|
+
});
|
|
1054
|
+
return outboundRecord(
|
|
1055
|
+
spaceId,
|
|
1056
|
+
receiptGuid(receipt),
|
|
1057
|
+
content,
|
|
1058
|
+
receiptTimestamp(receipt)
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1028
1061
|
case "poll":
|
|
1029
1062
|
if (replyTo) {
|
|
1030
1063
|
throw unsupportedRemoteContent(
|
|
@@ -1032,18 +1065,24 @@ var sendContent = async (remote, chat, content, replyTo) => {
|
|
|
1032
1065
|
"polls cannot be sent as replies"
|
|
1033
1066
|
);
|
|
1034
1067
|
}
|
|
1035
|
-
return
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1068
|
+
return outboundRecord(
|
|
1069
|
+
spaceId,
|
|
1070
|
+
receiptGuid(
|
|
1071
|
+
await remote.polls.create(
|
|
1072
|
+
chat,
|
|
1073
|
+
content.title,
|
|
1074
|
+
content.options.map((option) => option.title)
|
|
1075
|
+
)
|
|
1076
|
+
),
|
|
1077
|
+
content,
|
|
1078
|
+
/* @__PURE__ */ new Date()
|
|
1041
1079
|
);
|
|
1042
1080
|
default:
|
|
1043
1081
|
throw unsupportedRemoteContent(content.type);
|
|
1044
1082
|
}
|
|
1045
1083
|
};
|
|
1046
1084
|
var validateGroupContent = (content) => {
|
|
1085
|
+
let textCount = 0;
|
|
1047
1086
|
for (const sub of content.items) {
|
|
1048
1087
|
const itemType = sub.content.type;
|
|
1049
1088
|
if (!GROUP_ITEM_ALLOWED.has(itemType)) {
|
|
@@ -1052,32 +1091,69 @@ var validateGroupContent = (content) => {
|
|
|
1052
1091
|
`"${itemType}" items are not supported inside a group`
|
|
1053
1092
|
);
|
|
1054
1093
|
}
|
|
1094
|
+
if (itemType === "text" && ++textCount > MAX_GROUP_TEXT_ITEMS) {
|
|
1095
|
+
throw unsupportedRemoteContent(
|
|
1096
|
+
"group",
|
|
1097
|
+
`groups can contain at most ${MAX_GROUP_TEXT_ITEMS} text item`
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
var resolvePart = async (remote, content) => {
|
|
1103
|
+
switch (content.type) {
|
|
1104
|
+
case "text":
|
|
1105
|
+
return { text: content.text };
|
|
1106
|
+
case "attachment": {
|
|
1107
|
+
const { guid, name } = await uploadAttachment(remote, content);
|
|
1108
|
+
return { attachmentGuid: guid, attachmentName: name };
|
|
1109
|
+
}
|
|
1110
|
+
case "contact": {
|
|
1111
|
+
const { guid, name } = await sendContactAttachment(remote, content);
|
|
1112
|
+
return { attachmentGuid: guid, attachmentName: name };
|
|
1113
|
+
}
|
|
1114
|
+
case "voice": {
|
|
1115
|
+
const { guid, name } = await uploadVoice(remote, content);
|
|
1116
|
+
return { attachmentGuid: guid, attachmentName: name };
|
|
1117
|
+
}
|
|
1118
|
+
default:
|
|
1119
|
+
throw unsupportedRemoteContent(content.type);
|
|
1055
1120
|
}
|
|
1056
1121
|
};
|
|
1057
1122
|
var send3 = async (remote, spaceId, content) => {
|
|
1058
1123
|
const chat = chatGuid2(spaceId);
|
|
1059
1124
|
if (content.type === "group") {
|
|
1060
1125
|
validateGroupContent(content);
|
|
1061
|
-
const
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
const
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1126
|
+
const resolved = await Promise.all(
|
|
1127
|
+
content.items.map((sub) => resolvePart(remote, sub.content))
|
|
1128
|
+
);
|
|
1129
|
+
const receipt = await remote.messages.sendMultipart(
|
|
1130
|
+
chat,
|
|
1131
|
+
resolved.map((part, idx) => ({ ...part, partIndex: idx }))
|
|
1132
|
+
);
|
|
1133
|
+
const parentGuid = receiptGuid(receipt);
|
|
1134
|
+
const timestamp = receiptTimestamp(receipt);
|
|
1135
|
+
const items = content.items.map(
|
|
1136
|
+
(sub, idx) => outboundRecord(
|
|
1137
|
+
spaceId,
|
|
1138
|
+
formatChildId(idx, parentGuid),
|
|
1139
|
+
sub.content,
|
|
1140
|
+
timestamp,
|
|
1141
|
+
{ partIndex: idx, parentId: parentGuid }
|
|
1142
|
+
)
|
|
1143
|
+
);
|
|
1144
|
+
return outboundRecord(
|
|
1145
|
+
spaceId,
|
|
1146
|
+
parentGuid,
|
|
1147
|
+
asGroup({ items }),
|
|
1148
|
+
timestamp
|
|
1149
|
+
);
|
|
1074
1150
|
}
|
|
1075
|
-
return sendContent(remote, chat, content);
|
|
1151
|
+
return sendContent(remote, spaceId, chat, content);
|
|
1076
1152
|
};
|
|
1077
1153
|
var replyToMessage = async (remote, spaceId, msgId, content) => {
|
|
1078
1154
|
const chat = chatGuid2(spaceId);
|
|
1079
1155
|
const replyTo = messageGuid3(msgId);
|
|
1080
|
-
return sendContent(remote, chat, content, replyTo);
|
|
1156
|
+
return sendContent(remote, spaceId, chat, content, replyTo);
|
|
1081
1157
|
};
|
|
1082
1158
|
var editMessage = async (remote, spaceId, msgId, content) => {
|
|
1083
1159
|
if (content.type !== "text") {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as Platform, c as PlatformDef, P as ProviderMessage, M as Message } from '../../types-
|
|
1
|
+
import { d as Platform, c as PlatformDef, P as ProviderMessage, M as Message } from '../../types-GhOtIIqj.js';
|
|
2
2
|
import z__default from 'zod';
|
|
3
3
|
import 'hotscript';
|
|
4
4
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
asVoice
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-QZ5DJ7VR.js";
|
|
4
4
|
import {
|
|
5
5
|
UnsupportedError,
|
|
6
6
|
asAttachment,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
fromVCard,
|
|
11
11
|
reactionSchema,
|
|
12
12
|
toVCard
|
|
13
|
-
} from "../../chunk-
|
|
13
|
+
} from "../../chunk-5GQ2OMFY.js";
|
|
14
14
|
|
|
15
15
|
// src/providers/terminal/index.ts
|
|
16
16
|
import { spawn } from "child_process";
|
|
@@ -601,6 +601,14 @@ function parseTimestamp(s) {
|
|
|
601
601
|
const t = Date.parse(s);
|
|
602
602
|
return Number.isNaN(t) ? /* @__PURE__ */ new Date() : new Date(t);
|
|
603
603
|
}
|
|
604
|
+
function buildOutboundRecord(result, content, spaceId) {
|
|
605
|
+
return {
|
|
606
|
+
id: result.id,
|
|
607
|
+
content,
|
|
608
|
+
space: { id: spaceId },
|
|
609
|
+
timestamp: parseTimestamp(result.timestamp)
|
|
610
|
+
};
|
|
611
|
+
}
|
|
604
612
|
function reactionTargetFromProtocol(reaction) {
|
|
605
613
|
const target = {
|
|
606
614
|
id: reaction.messageId,
|
|
@@ -810,7 +818,7 @@ var terminal = definePlatform("terminal", {
|
|
|
810
818
|
"send",
|
|
811
819
|
{ spaceId: space.id, content: proto }
|
|
812
820
|
);
|
|
813
|
-
return
|
|
821
|
+
return buildOutboundRecord(result, content, space.id);
|
|
814
822
|
},
|
|
815
823
|
startTyping: async ({ client, space }) => {
|
|
816
824
|
const c = client;
|
|
@@ -835,7 +843,7 @@ var terminal = definePlatform("terminal", {
|
|
|
835
843
|
"replyToMessage",
|
|
836
844
|
{ spaceId: space.id, messageId, content: proto }
|
|
837
845
|
);
|
|
838
|
-
return
|
|
846
|
+
return buildOutboundRecord(result, content, space.id);
|
|
839
847
|
}
|
|
840
848
|
}
|
|
841
849
|
});
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage, i as ManagedStream } from '../../types-GhOtIIqj.js';
|
|
2
2
|
import { WhatsAppClient } from '@photon-ai/whatsapp-business';
|
|
3
3
|
import * as z from 'zod';
|
|
4
4
|
import z__default from 'zod';
|
|
5
|
-
import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-BZhWdyLk.js';
|
|
6
5
|
import * as zod_v4_core from 'zod/v4/core';
|
|
7
6
|
import 'hotscript';
|
|
8
7
|
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
cloud,
|
|
4
4
|
mergeStreams,
|
|
5
5
|
stream
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-FF2R4EP3.js";
|
|
7
7
|
import {
|
|
8
8
|
UnsupportedError,
|
|
9
9
|
asAttachment,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
asReaction,
|
|
13
13
|
asText,
|
|
14
14
|
definePlatform
|
|
15
|
-
} from "../../chunk-
|
|
15
|
+
} from "../../chunk-5GQ2OMFY.js";
|
|
16
16
|
|
|
17
17
|
// src/providers/whatsapp-business/index.ts
|
|
18
18
|
import { createClient as createClient2 } from "@photon-ai/whatsapp-business";
|
|
@@ -266,8 +266,11 @@ var primary = (clients) => {
|
|
|
266
266
|
}
|
|
267
267
|
return client;
|
|
268
268
|
};
|
|
269
|
-
var
|
|
270
|
-
id: result.messageId
|
|
269
|
+
var toRecord = (result, spaceId, content) => ({
|
|
270
|
+
id: result.messageId,
|
|
271
|
+
content,
|
|
272
|
+
space: { id: spaceId },
|
|
273
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
271
274
|
});
|
|
272
275
|
var MAX_POLL_CACHE_SIZE = 1e3;
|
|
273
276
|
var OPTION_ID_PREFIX = "opt_";
|
|
@@ -622,8 +625,10 @@ var send = async (clients, spaceId, content) => {
|
|
|
622
625
|
const client = primary(clients);
|
|
623
626
|
switch (content.type) {
|
|
624
627
|
case "text":
|
|
625
|
-
return
|
|
626
|
-
await client.messages.send({ to: spaceId, text: content.text })
|
|
628
|
+
return toRecord(
|
|
629
|
+
await client.messages.send({ to: spaceId, text: content.text }),
|
|
630
|
+
spaceId,
|
|
631
|
+
content
|
|
627
632
|
);
|
|
628
633
|
case "attachment": {
|
|
629
634
|
const { mediaId } = await client.media.upload({
|
|
@@ -633,19 +638,23 @@ var send = async (clients, spaceId, content) => {
|
|
|
633
638
|
});
|
|
634
639
|
const mediaType = mimeToMediaType(content.mimeType);
|
|
635
640
|
const mediaPayload = mediaType === "document" ? { id: mediaId, filename: content.name } : { id: mediaId };
|
|
636
|
-
return
|
|
641
|
+
return toRecord(
|
|
637
642
|
await client.messages.send({
|
|
638
643
|
to: spaceId,
|
|
639
644
|
[mediaType]: mediaPayload
|
|
640
|
-
})
|
|
645
|
+
}),
|
|
646
|
+
spaceId,
|
|
647
|
+
content
|
|
641
648
|
);
|
|
642
649
|
}
|
|
643
650
|
case "contact":
|
|
644
|
-
return
|
|
651
|
+
return toRecord(
|
|
645
652
|
await client.messages.send({
|
|
646
653
|
to: spaceId,
|
|
647
654
|
contacts: [contactToWa(content)]
|
|
648
|
-
})
|
|
655
|
+
}),
|
|
656
|
+
spaceId,
|
|
657
|
+
content
|
|
649
658
|
);
|
|
650
659
|
case "voice": {
|
|
651
660
|
const { mediaId } = await client.media.upload({
|
|
@@ -653,11 +662,13 @@ var send = async (clients, spaceId, content) => {
|
|
|
653
662
|
mimeType: content.mimeType,
|
|
654
663
|
filename: voiceFilename(content)
|
|
655
664
|
});
|
|
656
|
-
return
|
|
665
|
+
return toRecord(
|
|
657
666
|
await client.messages.send({
|
|
658
667
|
to: spaceId,
|
|
659
668
|
audio: { id: mediaId }
|
|
660
|
-
})
|
|
669
|
+
}),
|
|
670
|
+
spaceId,
|
|
671
|
+
content
|
|
661
672
|
);
|
|
662
673
|
}
|
|
663
674
|
case "poll": {
|
|
@@ -666,7 +677,7 @@ var send = async (clients, spaceId, content) => {
|
|
|
666
677
|
interactive: pollToInteractive(content)
|
|
667
678
|
});
|
|
668
679
|
cachePoll(client, result.messageId, content);
|
|
669
|
-
return
|
|
680
|
+
return toRecord(result, spaceId, content);
|
|
670
681
|
}
|
|
671
682
|
default:
|
|
672
683
|
throw UnsupportedError.content(content.type);
|
|
@@ -682,12 +693,14 @@ var replyToMessage = async (clients, spaceId, messageId, content) => {
|
|
|
682
693
|
const client = primary(clients);
|
|
683
694
|
switch (content.type) {
|
|
684
695
|
case "text":
|
|
685
|
-
return
|
|
696
|
+
return toRecord(
|
|
686
697
|
await client.messages.send({
|
|
687
698
|
to: spaceId,
|
|
688
699
|
replyTo: messageId,
|
|
689
700
|
text: content.text
|
|
690
|
-
})
|
|
701
|
+
}),
|
|
702
|
+
spaceId,
|
|
703
|
+
content
|
|
691
704
|
);
|
|
692
705
|
case "attachment": {
|
|
693
706
|
const { mediaId } = await client.media.upload({
|
|
@@ -697,21 +710,25 @@ var replyToMessage = async (clients, spaceId, messageId, content) => {
|
|
|
697
710
|
});
|
|
698
711
|
const mediaType = mimeToMediaType(content.mimeType);
|
|
699
712
|
const mediaPayload = mediaType === "document" ? { id: mediaId, filename: content.name } : { id: mediaId };
|
|
700
|
-
return
|
|
713
|
+
return toRecord(
|
|
701
714
|
await client.messages.send({
|
|
702
715
|
to: spaceId,
|
|
703
716
|
replyTo: messageId,
|
|
704
717
|
[mediaType]: mediaPayload
|
|
705
|
-
})
|
|
718
|
+
}),
|
|
719
|
+
spaceId,
|
|
720
|
+
content
|
|
706
721
|
);
|
|
707
722
|
}
|
|
708
723
|
case "contact":
|
|
709
|
-
return
|
|
724
|
+
return toRecord(
|
|
710
725
|
await client.messages.send({
|
|
711
726
|
to: spaceId,
|
|
712
727
|
replyTo: messageId,
|
|
713
728
|
contacts: [contactToWa(content)]
|
|
714
|
-
})
|
|
729
|
+
}),
|
|
730
|
+
spaceId,
|
|
731
|
+
content
|
|
715
732
|
);
|
|
716
733
|
case "voice": {
|
|
717
734
|
const { mediaId } = await client.media.upload({
|
|
@@ -719,12 +736,14 @@ var replyToMessage = async (clients, spaceId, messageId, content) => {
|
|
|
719
736
|
mimeType: content.mimeType,
|
|
720
737
|
filename: voiceFilename(content)
|
|
721
738
|
});
|
|
722
|
-
return
|
|
739
|
+
return toRecord(
|
|
723
740
|
await client.messages.send({
|
|
724
741
|
to: spaceId,
|
|
725
742
|
replyTo: messageId,
|
|
726
743
|
audio: { id: mediaId }
|
|
727
|
-
})
|
|
744
|
+
}),
|
|
745
|
+
spaceId,
|
|
746
|
+
content
|
|
728
747
|
);
|
|
729
748
|
}
|
|
730
749
|
case "poll": {
|
|
@@ -734,7 +753,7 @@ var replyToMessage = async (clients, spaceId, messageId, content) => {
|
|
|
734
753
|
interactive: pollToInteractive(content)
|
|
735
754
|
});
|
|
736
755
|
cachePoll(client, result.messageId, content);
|
|
737
|
-
return
|
|
756
|
+
return toRecord(result, spaceId, content);
|
|
738
757
|
}
|
|
739
758
|
default:
|
|
740
759
|
throw UnsupportedError.content(content.type);
|
|
@@ -166,6 +166,18 @@ interface OutboundMessage<TPlatform extends string = string, TSender extends Use
|
|
|
166
166
|
}
|
|
167
167
|
type Message<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> = InboundMessage<TPlatform, TSender, TSpace> | OutboundMessage<TPlatform, TSender, TSpace>;
|
|
168
168
|
|
|
169
|
+
interface ManagedStream<T> extends AsyncIterable<T> {
|
|
170
|
+
close(): Promise<void>;
|
|
171
|
+
}
|
|
172
|
+
type StreamCleanup = void | (() => void | Promise<void>);
|
|
173
|
+
declare function stream<T>(setup: (emit: (value: T) => Promise<void>, end: (error?: unknown) => void) => StreamCleanup | Promise<StreamCleanup>): ManagedStream<T>;
|
|
174
|
+
declare function mergeStreams<T>(streams: readonly ManagedStream<T>[]): ManagedStream<T>;
|
|
175
|
+
interface Broadcaster<T> {
|
|
176
|
+
close(): Promise<void>;
|
|
177
|
+
subscribe(): ManagedStream<T>;
|
|
178
|
+
}
|
|
179
|
+
declare function broadcast<T>(source: ManagedStream<T>): Broadcaster<T>;
|
|
180
|
+
|
|
169
181
|
type ResolvedSpace = Pick<Space, "id">;
|
|
170
182
|
type SpaceRef = Pick<Space, "id" | "__platform">;
|
|
171
183
|
type ResolvedUser = Pick<User, "id">;
|
|
@@ -187,19 +199,28 @@ type ProviderMessage<TSender extends ResolvedUser = ResolvedUser, TSpace extends
|
|
|
187
199
|
space: TSpace;
|
|
188
200
|
timestamp?: Date;
|
|
189
201
|
} & TExtra;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
202
|
+
/**
|
|
203
|
+
* A message a provider produced — used for both inbound (`events.messages`,
|
|
204
|
+
* `getMessage`) and outbound (`send`, `replyToMessage`) flows. Providers
|
|
205
|
+
* return their native record shape (including platform extras like
|
|
206
|
+
* `partIndex`/`parentId` for iMessage) and the platform `wrapProviderMessage`
|
|
207
|
+
* pipeline turns it into a fully-built Message.
|
|
208
|
+
*
|
|
209
|
+
* `sender` is optional because outbound sends often can't synthesize one
|
|
210
|
+
* (the SDK doesn't surface the bot's own handle); inbound providers are
|
|
211
|
+
* expected to populate it.
|
|
212
|
+
*/
|
|
213
|
+
type ProviderMessageRecord = {
|
|
199
214
|
id: string;
|
|
200
|
-
|
|
215
|
+
content: Content;
|
|
216
|
+
sender?: {
|
|
217
|
+
id: string;
|
|
218
|
+
} & Record<string, unknown>;
|
|
219
|
+
space: {
|
|
220
|
+
id: string;
|
|
221
|
+
} & Record<string, unknown>;
|
|
201
222
|
timestamp?: Date;
|
|
202
|
-
}
|
|
223
|
+
} & Record<string, unknown>;
|
|
203
224
|
type MergeSchema<TSchema extends z__default.ZodType | undefined, TBase extends object> = TSchema extends z__default.ZodType ? string extends keyof z__default.infer<TSchema> ? TBase : Omit<z__default.infer<TSchema>, keyof TBase> & TBase : TBase;
|
|
204
225
|
type SchemaMessage<TUserSchema extends z__default.ZodType | undefined = undefined, TSpaceSchema extends z__default.ZodType | undefined = undefined> = ProviderMessage<MergeSchema<TUserSchema, ResolvedUser>, MergeSchema<TSpaceSchema, ResolvedSpace>>;
|
|
205
226
|
type InferEventPayload<T> = T extends (ctx: never) => AsyncIterable<infer P> ? P : never;
|
|
@@ -215,7 +236,7 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
|
|
|
215
236
|
content: Content;
|
|
216
237
|
client: _Client;
|
|
217
238
|
config: z__default.infer<_ConfigSchema>;
|
|
218
|
-
}) => Promise<
|
|
239
|
+
}) => Promise<ProviderMessageRecord>;
|
|
219
240
|
startTyping?: (_: {
|
|
220
241
|
space: _ResolvedSpace & SpaceRef;
|
|
221
242
|
client: _Client;
|
|
@@ -240,7 +261,7 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
|
|
|
240
261
|
content: Content;
|
|
241
262
|
client: _Client;
|
|
242
263
|
config: z__default.infer<_ConfigSchema>;
|
|
243
|
-
}) => Promise<
|
|
264
|
+
}) => Promise<ProviderMessageRecord>;
|
|
244
265
|
editMessage?: (_: {
|
|
245
266
|
space: _ResolvedSpace & SpaceRef;
|
|
246
267
|
messageId: string;
|
|
@@ -298,11 +319,11 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
|
|
|
298
319
|
}
|
|
299
320
|
interface AnyPlatformDef {
|
|
300
321
|
actions: {
|
|
301
|
-
send: (_: any) => Promise<
|
|
322
|
+
send: (_: any) => Promise<ProviderMessageRecord>;
|
|
302
323
|
startTyping?: (_: any) => Promise<void>;
|
|
303
324
|
stopTyping?: (_: any) => Promise<void>;
|
|
304
325
|
reactToMessage?: (_: any) => Promise<void>;
|
|
305
|
-
replyToMessage?: (_: any) => Promise<
|
|
326
|
+
replyToMessage?: (_: any) => Promise<ProviderMessageRecord>;
|
|
306
327
|
editMessage?: (_: any) => Promise<void>;
|
|
307
328
|
getMessage?: (_: any) => Promise<any>;
|
|
308
329
|
};
|
|
@@ -380,20 +401,27 @@ type SpaceVarargArgs<Def extends AnyPlatformDef> = [
|
|
|
380
401
|
type SpaceArgs<Def extends AnyPlatformDef> = SpaceArrayArgs<Def> | SpaceVarargArgs<Def>;
|
|
381
402
|
type PlatformSpace<Def extends AnyPlatformDef> = Omit<SpaceShapeOf<Def>, keyof Space> & Space;
|
|
382
403
|
type PlatformMessage<Def extends AnyPlatformDef> = Omit<SchemaInfer<Def["message"]>, keyof Message> & Message<Def["name"], PlatformUser<Def>, PlatformSpace<Def>>;
|
|
404
|
+
type InboundPlatformMessage<Def extends AnyPlatformDef> = Omit<SchemaInfer<Def["message"]>, keyof InboundMessage> & InboundMessage<Def["name"], PlatformUser<Def>, PlatformSpace<Def>>;
|
|
383
405
|
type PlatformUser<Def extends AnyPlatformDef> = Omit<ResolvedUserOf<Def>, keyof User> & User;
|
|
384
406
|
type PlatformInstance<Def extends AnyPlatformDef> = {
|
|
407
|
+
readonly messages: AsyncIterable<[
|
|
408
|
+
PlatformSpace<Def>,
|
|
409
|
+
InboundPlatformMessage<Def>
|
|
410
|
+
]>;
|
|
385
411
|
space(...args: SpaceArgs<Def>): Promise<PlatformSpace<Def>>;
|
|
386
412
|
user(userID: string): Promise<PlatformUser<Def>>;
|
|
387
413
|
} & {
|
|
388
414
|
[K in Exclude<keyof Def["events"], "messages" | symbol | number> as K extends ReservedNames ? never : K]: AsyncIterable<InferEventPayload<Def["events"][K]>>;
|
|
389
415
|
};
|
|
416
|
+
interface PlatformRuntime {
|
|
417
|
+
client: unknown;
|
|
418
|
+
config: unknown;
|
|
419
|
+
definition: AnyPlatformDef;
|
|
420
|
+
subscribeMessages: () => ManagedStream<[Space, InboundMessage]>;
|
|
421
|
+
}
|
|
390
422
|
interface SpectrumLike<Providers extends PlatformProviderConfig[] = PlatformProviderConfig[]> {
|
|
391
423
|
readonly __internal: {
|
|
392
|
-
platforms: Map<string,
|
|
393
|
-
client: unknown;
|
|
394
|
-
config: unknown;
|
|
395
|
-
definition: AnyPlatformDef;
|
|
396
|
-
}>;
|
|
424
|
+
platforms: Map<string, PlatformRuntime>;
|
|
397
425
|
};
|
|
398
426
|
readonly __providers: Providers;
|
|
399
427
|
}
|
|
@@ -404,4 +432,4 @@ interface Platform<Def extends AnyPlatformDef> {
|
|
|
404
432
|
(message: Message): PlatformMessage<Def>;
|
|
405
433
|
}
|
|
406
434
|
|
|
407
|
-
export type
|
|
435
|
+
export { type AnyPlatformDef as A, type Broadcaster as B, type ContentBuilder as C, type EventProducer as E, type InboundMessage as I, type Message as M, type OutboundMessage as O, type ProviderMessage as P, type SpectrumLike as S, type User as U, type ContentInput as a, type Content as b, type PlatformDef as c, type Platform as d, type PlatformProviderConfig as e, type CustomEventStreams as f, type Space as g, type InboundPlatformMessage as h, type ManagedStream as i, type PlatformInstance as j, type PlatformMessage as k, type PlatformRuntime as l, type PlatformSpace as m, type PlatformUser as n, type SchemaMessage as o, broadcast as p, mergeStreams as q, stream as s };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spectrum-ts",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@photon-ai/advanced-imessage": "^0.
|
|
22
|
+
"@photon-ai/advanced-imessage": "^0.6.0",
|
|
23
23
|
"@photon-ai/imessage-kit": "^3.0.0",
|
|
24
24
|
"@photon-ai/whatsapp-business": "^0.1.1",
|
|
25
25
|
"@repeaterjs/repeater": "^3.0.6",
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
interface ManagedStream<T> extends AsyncIterable<T> {
|
|
2
|
-
close(): Promise<void>;
|
|
3
|
-
}
|
|
4
|
-
type StreamCleanup = void | (() => void | Promise<void>);
|
|
5
|
-
declare function stream<T>(setup: (emit: (value: T) => Promise<void>, end: (error?: unknown) => void) => StreamCleanup | Promise<StreamCleanup>): ManagedStream<T>;
|
|
6
|
-
declare function mergeStreams<T>(streams: readonly ManagedStream<T>[]): ManagedStream<T>;
|
|
7
|
-
|
|
8
|
-
export { type ManagedStream as M, mergeStreams as m, stream as s };
|