spectrum-ts 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-UZWRB3FZ.js +624 -0
- package/dist/index.d.ts +133 -3
- package/dist/index.js +130 -13
- package/dist/providers/imessage/index.d.ts +1 -1
- package/dist/providers/imessage/index.js +297 -46
- package/dist/providers/terminal/index.d.ts +1 -1
- package/dist/providers/whatsapp-business/index.d.ts +1 -1
- package/dist/providers/whatsapp-business/index.js +257 -14
- package/dist/{types-BdWMydUJ.d.ts → types-CfiD_00g.d.ts} +69 -5
- package/package.json +9 -2
- package/dist/chunk-5XW4CAWS.js +0 -165
|
@@ -3,10 +3,13 @@ import {
|
|
|
3
3
|
} from "../../chunk-HXM64ENV.js";
|
|
4
4
|
import {
|
|
5
5
|
asAttachment,
|
|
6
|
+
asContact,
|
|
6
7
|
asCustom,
|
|
8
|
+
fromVCard,
|
|
7
9
|
mergeStreams,
|
|
8
|
-
stream
|
|
9
|
-
|
|
10
|
+
stream,
|
|
11
|
+
toVCard
|
|
12
|
+
} from "../../chunk-UZWRB3FZ.js";
|
|
10
13
|
import {
|
|
11
14
|
asText,
|
|
12
15
|
definePlatform
|
|
@@ -104,41 +107,66 @@ async function disposeCloudAuth(clients) {
|
|
|
104
107
|
|
|
105
108
|
// src/providers/imessage/local.ts
|
|
106
109
|
import { createReadStream } from "fs";
|
|
107
|
-
import {
|
|
110
|
+
import { mkdtemp, rm, writeFile } from "fs/promises";
|
|
108
111
|
import { tmpdir } from "os";
|
|
109
|
-
import { join } from "path";
|
|
112
|
+
import { basename, join } from "path";
|
|
110
113
|
import { Readable } from "stream";
|
|
111
114
|
import {
|
|
112
115
|
readAttachmentBytes
|
|
113
116
|
} from "@photon-ai/imessage-kit";
|
|
114
117
|
var DEFAULT_ATTACHMENT_NAME = "attachment";
|
|
118
|
+
var VCARD_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
119
|
+
"text/vcard",
|
|
120
|
+
"text/x-vcard",
|
|
121
|
+
"text/directory",
|
|
122
|
+
"application/vcard",
|
|
123
|
+
"application/x-vcard"
|
|
124
|
+
]);
|
|
125
|
+
var normalizeMimeType = (mimeType) => (mimeType.split(";")[0] ?? "").trim().toLowerCase();
|
|
126
|
+
var isVCardAttachment = (mimeType, fileName) => {
|
|
127
|
+
if (mimeType && VCARD_MIME_TYPES.has(normalizeMimeType(mimeType))) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
return Boolean(fileName?.toLowerCase().endsWith(".vcf"));
|
|
131
|
+
};
|
|
115
132
|
var toSpace = (message) => ({
|
|
116
133
|
id: message.chatId,
|
|
117
134
|
type: message.chatKind === "group" ? "group" : "dm"
|
|
118
135
|
});
|
|
119
|
-
var
|
|
136
|
+
var toAttachmentContent = (att) => {
|
|
137
|
+
const { localPath } = att;
|
|
138
|
+
return asAttachment({
|
|
139
|
+
name: att.fileName ?? DEFAULT_ATTACHMENT_NAME,
|
|
140
|
+
mimeType: att.mimeType,
|
|
141
|
+
size: att.sizeBytes,
|
|
142
|
+
read: () => readAttachmentBytes(att),
|
|
143
|
+
stream: localPath ? async () => Readable.toWeb(
|
|
144
|
+
createReadStream(localPath)
|
|
145
|
+
) : void 0
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
var toVCardContent = async (att) => {
|
|
149
|
+
try {
|
|
150
|
+
const buf = await readAttachmentBytes(att);
|
|
151
|
+
return asContact(fromVCard(buf.toString("utf8")));
|
|
152
|
+
} catch {
|
|
153
|
+
return toAttachmentContent(att);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
var toMessages = async (message) => {
|
|
120
157
|
const base = {
|
|
121
158
|
sender: { id: message.participant ?? "" },
|
|
122
159
|
space: toSpace(message),
|
|
123
160
|
timestamp: message.createdAt
|
|
124
161
|
};
|
|
125
162
|
if (message.attachments.length > 0) {
|
|
126
|
-
return
|
|
127
|
-
|
|
128
|
-
return {
|
|
163
|
+
return Promise.all(
|
|
164
|
+
message.attachments.map(async (att) => ({
|
|
129
165
|
...base,
|
|
130
166
|
id: `${message.id}:${att.id}`,
|
|
131
|
-
content:
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
size: att.sizeBytes,
|
|
135
|
-
read: () => readAttachmentBytes(att),
|
|
136
|
-
stream: localPath ? async () => Readable.toWeb(
|
|
137
|
-
createReadStream(localPath)
|
|
138
|
-
) : void 0
|
|
139
|
-
})
|
|
140
|
-
};
|
|
141
|
-
});
|
|
167
|
+
content: isVCardAttachment(att.mimeType, att.fileName) ? await toVCardContent(att) : toAttachmentContent(att)
|
|
168
|
+
}))
|
|
169
|
+
);
|
|
142
170
|
}
|
|
143
171
|
return [
|
|
144
172
|
{
|
|
@@ -149,33 +177,50 @@ var toMessages = (message) => {
|
|
|
149
177
|
];
|
|
150
178
|
};
|
|
151
179
|
var messages = (client) => stream((emit, end) => {
|
|
180
|
+
let lastPromise = Promise.resolve();
|
|
152
181
|
client.startWatching({
|
|
153
182
|
onMessage: (message) => {
|
|
154
|
-
|
|
155
|
-
for (const m of
|
|
183
|
+
lastPromise = lastPromise.then(() => toMessages(message)).then((ms) => {
|
|
184
|
+
for (const m of ms) {
|
|
156
185
|
emit(m);
|
|
157
186
|
}
|
|
158
|
-
}
|
|
159
|
-
end(error);
|
|
160
|
-
}
|
|
187
|
+
}).catch((error) => end(error));
|
|
161
188
|
}
|
|
162
189
|
});
|
|
163
190
|
return () => client.stopWatching();
|
|
164
191
|
});
|
|
192
|
+
var vcardFileName = (content) => {
|
|
193
|
+
const base = content.name?.formatted ?? content.user?.id ?? "contact";
|
|
194
|
+
return `${base.replace(/[^a-zA-Z0-9_\-.]/g, "_")}.vcf`;
|
|
195
|
+
};
|
|
196
|
+
var sendTempFile = async (client, spaceId, name, data) => {
|
|
197
|
+
const safeName = basename(name) || DEFAULT_ATTACHMENT_NAME;
|
|
198
|
+
const dir = await mkdtemp(join(tmpdir(), "spectrum-"));
|
|
199
|
+
const tmp = join(dir, safeName);
|
|
200
|
+
await writeFile(tmp, data);
|
|
201
|
+
try {
|
|
202
|
+
await client.send(spaceId, { attachments: [tmp] });
|
|
203
|
+
} finally {
|
|
204
|
+
await rm(dir, { recursive: true, force: true }).catch(() => {
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
};
|
|
165
208
|
var send = async (client, spaceId, content) => {
|
|
166
209
|
switch (content.type) {
|
|
167
210
|
case "text":
|
|
168
211
|
await client.send(spaceId, content.text);
|
|
169
212
|
break;
|
|
170
|
-
case "attachment":
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
213
|
+
case "attachment":
|
|
214
|
+
await sendTempFile(client, spaceId, content.name, await content.read());
|
|
215
|
+
break;
|
|
216
|
+
case "contact": {
|
|
217
|
+
const vcf = await toVCard(content);
|
|
218
|
+
await sendTempFile(
|
|
219
|
+
client,
|
|
220
|
+
spaceId,
|
|
221
|
+
vcardFileName(content),
|
|
222
|
+
Buffer.from(vcf, "utf8")
|
|
223
|
+
);
|
|
179
224
|
break;
|
|
180
225
|
}
|
|
181
226
|
default:
|
|
@@ -189,6 +234,144 @@ import {
|
|
|
189
234
|
messageGuid,
|
|
190
235
|
Reaction
|
|
191
236
|
} from "@photon-ai/advanced-imessage";
|
|
237
|
+
|
|
238
|
+
// src/utils/audio.ts
|
|
239
|
+
import { spawn } from "child_process";
|
|
240
|
+
import { mkdtemp as mkdtemp2, readFile, rm as rm2, writeFile as writeFile2 } from "fs/promises";
|
|
241
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
242
|
+
import { join as join2 } from "path";
|
|
243
|
+
var M4A_BRANDS = /* @__PURE__ */ new Set([
|
|
244
|
+
"M4A ",
|
|
245
|
+
"M4B ",
|
|
246
|
+
"M4P ",
|
|
247
|
+
"mp42",
|
|
248
|
+
"mp41",
|
|
249
|
+
"isom",
|
|
250
|
+
"iso2"
|
|
251
|
+
]);
|
|
252
|
+
var M4A_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
253
|
+
"audio/mp4",
|
|
254
|
+
"audio/mp4a-latm",
|
|
255
|
+
"audio/x-m4a",
|
|
256
|
+
"audio/aac",
|
|
257
|
+
"audio/aacp"
|
|
258
|
+
]);
|
|
259
|
+
var FFMPEG_MISSING_MESSAGE = "voice content: input is not m4a/aac and ffmpeg is unavailable. Install `ffmpeg-static` or ensure `ffmpeg` is on PATH.";
|
|
260
|
+
var isM4a = (buffer) => {
|
|
261
|
+
if (buffer.length < 12) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
if (buffer.toString("ascii", 4, 8) !== "ftyp") {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
return M4A_BRANDS.has(buffer.toString("ascii", 8, 12));
|
|
268
|
+
};
|
|
269
|
+
var isM4aMimeType = (mimeType) => M4A_MIME_TYPES.has(mimeType.toLowerCase());
|
|
270
|
+
var cachedFfmpegPath;
|
|
271
|
+
var tryStaticBinary = async () => {
|
|
272
|
+
try {
|
|
273
|
+
const mod = await import("ffmpeg-static");
|
|
274
|
+
return mod.default ?? void 0;
|
|
275
|
+
} catch {
|
|
276
|
+
return void 0;
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
var resolveFfmpegPath = async () => {
|
|
280
|
+
if (cachedFfmpegPath) {
|
|
281
|
+
return cachedFfmpegPath;
|
|
282
|
+
}
|
|
283
|
+
cachedFfmpegPath = await tryStaticBinary() ?? "ffmpeg";
|
|
284
|
+
return cachedFfmpegPath;
|
|
285
|
+
};
|
|
286
|
+
var collectStream = (stream2) => {
|
|
287
|
+
if (!stream2) {
|
|
288
|
+
return Promise.resolve("");
|
|
289
|
+
}
|
|
290
|
+
return new Promise((resolve, reject) => {
|
|
291
|
+
const chunks = [];
|
|
292
|
+
stream2.on("data", (chunk) => {
|
|
293
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
294
|
+
});
|
|
295
|
+
stream2.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
|
296
|
+
stream2.on("error", reject);
|
|
297
|
+
});
|
|
298
|
+
};
|
|
299
|
+
var isMissingBinaryError = (err) => err?.code === "ENOENT";
|
|
300
|
+
var runFfmpeg = (ffmpegPath, args) => {
|
|
301
|
+
const proc = spawn(ffmpegPath, args, { stdio: ["ignore", "ignore", "pipe"] });
|
|
302
|
+
const stderr = collectStream(proc.stderr);
|
|
303
|
+
const exit = new Promise((resolve, reject) => {
|
|
304
|
+
proc.on(
|
|
305
|
+
"error",
|
|
306
|
+
(err) => reject(
|
|
307
|
+
isMissingBinaryError(err) ? new Error(FFMPEG_MISSING_MESSAGE) : err
|
|
308
|
+
)
|
|
309
|
+
);
|
|
310
|
+
proc.on("exit", (code) => resolve(code ?? -1));
|
|
311
|
+
});
|
|
312
|
+
return Promise.all([exit, stderr]).then(([code, text]) => ({
|
|
313
|
+
code,
|
|
314
|
+
stderr: text
|
|
315
|
+
}));
|
|
316
|
+
};
|
|
317
|
+
var DURATION_PATTERN = /Duration:\s*(\d+):(\d{2}):(\d{2})(?:\.(\d{1,3}))?/;
|
|
318
|
+
var parseDuration = (stderr) => {
|
|
319
|
+
const match = stderr.match(DURATION_PATTERN);
|
|
320
|
+
if (!match) {
|
|
321
|
+
return void 0;
|
|
322
|
+
}
|
|
323
|
+
const [, hh, mm, ss, frac] = match;
|
|
324
|
+
const seconds = Number(hh) * 3600 + Number(mm) * 60 + Number(ss) + Number(`0.${frac ?? 0}`);
|
|
325
|
+
return Number.isFinite(seconds) ? seconds : void 0;
|
|
326
|
+
};
|
|
327
|
+
var transcodeToM4a = async (buffer) => {
|
|
328
|
+
const ffmpeg = await resolveFfmpegPath();
|
|
329
|
+
const dir = await mkdtemp2(join2(tmpdir2(), "spectrum-voice-"));
|
|
330
|
+
const inPath = join2(dir, "in");
|
|
331
|
+
const outPath = join2(dir, "out.m4a");
|
|
332
|
+
try {
|
|
333
|
+
await writeFile2(inPath, buffer);
|
|
334
|
+
const { code, stderr } = await runFfmpeg(ffmpeg, [
|
|
335
|
+
"-y",
|
|
336
|
+
"-i",
|
|
337
|
+
inPath,
|
|
338
|
+
"-f",
|
|
339
|
+
"ipod",
|
|
340
|
+
"-c:a",
|
|
341
|
+
"aac",
|
|
342
|
+
outPath
|
|
343
|
+
]);
|
|
344
|
+
if (code !== 0) {
|
|
345
|
+
throw new Error(`ffmpeg conversion failed (exit ${code}): ${stderr}`);
|
|
346
|
+
}
|
|
347
|
+
const out = await readFile(outPath);
|
|
348
|
+
return { buffer: out, duration: parseDuration(stderr) };
|
|
349
|
+
} finally {
|
|
350
|
+
await rm2(dir, { recursive: true, force: true }).catch(() => {
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
var ensureM4a = async (buffer, mimeType) => {
|
|
355
|
+
if (isM4aMimeType(mimeType) || isM4a(buffer)) {
|
|
356
|
+
return { buffer };
|
|
357
|
+
}
|
|
358
|
+
return transcodeToM4a(buffer);
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
// src/providers/imessage/remote.ts
|
|
362
|
+
var VCARD_MIME_TYPES2 = /* @__PURE__ */ new Set([
|
|
363
|
+
"text/vcard",
|
|
364
|
+
"text/x-vcard",
|
|
365
|
+
"text/directory",
|
|
366
|
+
"application/vcard",
|
|
367
|
+
"application/x-vcard"
|
|
368
|
+
]);
|
|
369
|
+
var isVCardAttachment2 = (mimeType, fileName) => {
|
|
370
|
+
if (mimeType && VCARD_MIME_TYPES2.has(mimeType.toLowerCase())) {
|
|
371
|
+
return true;
|
|
372
|
+
}
|
|
373
|
+
return Boolean(fileName?.toLowerCase().endsWith(".vcf"));
|
|
374
|
+
};
|
|
192
375
|
var TAPBACK_NAMES = new Set(
|
|
193
376
|
Object.values(Reaction).filter((r) => r !== "emoji" && r !== "sticker")
|
|
194
377
|
);
|
|
@@ -200,21 +383,32 @@ var baseMessage = (event) => ({
|
|
|
200
383
|
},
|
|
201
384
|
timestamp: event.timestamp
|
|
202
385
|
});
|
|
203
|
-
var
|
|
386
|
+
var toAttachmentContent2 = (client, info) => asAttachment({
|
|
387
|
+
name: info.fileName,
|
|
388
|
+
mimeType: info.mimeType,
|
|
389
|
+
size: info.totalBytes,
|
|
390
|
+
read: async () => Buffer.from(await client.attachments.downloadBuffer(info.guid)),
|
|
391
|
+
stream: async () => client.attachments.download(info.guid).stream
|
|
392
|
+
});
|
|
393
|
+
var toVCardContent2 = async (client, info) => {
|
|
394
|
+
try {
|
|
395
|
+
const buf = Buffer.from(await client.attachments.downloadBuffer(info.guid));
|
|
396
|
+
return asContact(fromVCard(buf.toString("utf8")));
|
|
397
|
+
} catch {
|
|
398
|
+
return toAttachmentContent2(client, info);
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
var toMessages2 = async (client, event) => {
|
|
204
402
|
const base = baseMessage(event);
|
|
205
403
|
const messageGuidStr = event.message.guid;
|
|
206
404
|
if (event.message.attachments.length > 0) {
|
|
207
|
-
return
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
read: async () => Buffer.from(await client.attachments.downloadBuffer(info.guid)),
|
|
215
|
-
stream: async () => client.attachments.download(info.guid).stream
|
|
216
|
-
})
|
|
217
|
-
}));
|
|
405
|
+
return Promise.all(
|
|
406
|
+
event.message.attachments.map(async (info) => ({
|
|
407
|
+
...base,
|
|
408
|
+
id: `${messageGuidStr}:${info.guid}`,
|
|
409
|
+
content: isVCardAttachment2(info.mimeType, info.fileName) ? await toVCardContent2(client, info) : toAttachmentContent2(client, info)
|
|
410
|
+
}))
|
|
411
|
+
);
|
|
218
412
|
}
|
|
219
413
|
const text = event.message.text;
|
|
220
414
|
return [
|
|
@@ -231,7 +425,7 @@ var clientStream = (client) => {
|
|
|
231
425
|
(async () => {
|
|
232
426
|
try {
|
|
233
427
|
for await (const event of sub) {
|
|
234
|
-
for (const message of toMessages2(client, event)) {
|
|
428
|
+
for (const message of await toMessages2(client, event)) {
|
|
235
429
|
emit(message);
|
|
236
430
|
}
|
|
237
431
|
}
|
|
@@ -243,6 +437,20 @@ var clientStream = (client) => {
|
|
|
243
437
|
return () => sub.close();
|
|
244
438
|
});
|
|
245
439
|
};
|
|
440
|
+
var sendVCardAttachment = (remote, name, vcf) => remote.attachments.upload({
|
|
441
|
+
data: Buffer.from(vcf, "utf8"),
|
|
442
|
+
fileName: name,
|
|
443
|
+
mimeType: "text/vcard"
|
|
444
|
+
});
|
|
445
|
+
var vcardFileName2 = (contact) => {
|
|
446
|
+
const base = contact.name?.formatted ?? contact.user?.id ?? "contact";
|
|
447
|
+
return `${base.replace(/[^a-zA-Z0-9_\-.]/g, "_")}.vcf`;
|
|
448
|
+
};
|
|
449
|
+
var sendContactAttachment = async (remote, content) => {
|
|
450
|
+
const vcf = await toVCard(content);
|
|
451
|
+
const upload = await sendVCardAttachment(remote, vcardFileName2(content), vcf);
|
|
452
|
+
return upload.guid;
|
|
453
|
+
};
|
|
246
454
|
var messages2 = (clients) => mergeStreams(clients.map(clientStream));
|
|
247
455
|
var startTyping = async (clients, spaceId) => {
|
|
248
456
|
const remote = clients[0];
|
|
@@ -278,6 +486,27 @@ var send2 = async (clients, spaceId, content) => {
|
|
|
278
486
|
});
|
|
279
487
|
break;
|
|
280
488
|
}
|
|
489
|
+
case "contact": {
|
|
490
|
+
const attachment = await sendContactAttachment(remote, content);
|
|
491
|
+
await remote.messages.send(chatGuid(spaceId), "", { attachment });
|
|
492
|
+
break;
|
|
493
|
+
}
|
|
494
|
+
case "voice": {
|
|
495
|
+
const { buffer } = await ensureM4a(
|
|
496
|
+
await content.read(),
|
|
497
|
+
content.mimeType
|
|
498
|
+
);
|
|
499
|
+
const attachment = await remote.attachments.upload({
|
|
500
|
+
data: buffer,
|
|
501
|
+
fileName: content.name ?? "voice.m4a",
|
|
502
|
+
mimeType: "audio/x-m4a"
|
|
503
|
+
});
|
|
504
|
+
await remote.messages.send(chatGuid(spaceId), "", {
|
|
505
|
+
attachment: attachment.guid,
|
|
506
|
+
audioMessage: true
|
|
507
|
+
});
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
281
510
|
default:
|
|
282
511
|
throw new Error(`Unsupported iMessage content type: ${content.type}`);
|
|
283
512
|
}
|
|
@@ -305,6 +534,28 @@ var replyToMessage = async (clients, spaceId, msgId, content) => {
|
|
|
305
534
|
});
|
|
306
535
|
break;
|
|
307
536
|
}
|
|
537
|
+
case "contact": {
|
|
538
|
+
const attachment = await sendContactAttachment(remote, content);
|
|
539
|
+
await remote.messages.send(chat, "", { attachment, replyTo });
|
|
540
|
+
break;
|
|
541
|
+
}
|
|
542
|
+
case "voice": {
|
|
543
|
+
const { buffer } = await ensureM4a(
|
|
544
|
+
await content.read(),
|
|
545
|
+
content.mimeType
|
|
546
|
+
);
|
|
547
|
+
const attachment = await remote.attachments.upload({
|
|
548
|
+
data: buffer,
|
|
549
|
+
fileName: content.name ?? "voice.m4a",
|
|
550
|
+
mimeType: "audio/x-m4a"
|
|
551
|
+
});
|
|
552
|
+
await remote.messages.send(chat, "", {
|
|
553
|
+
attachment: attachment.guid,
|
|
554
|
+
audioMessage: true,
|
|
555
|
+
replyTo
|
|
556
|
+
});
|
|
557
|
+
break;
|
|
558
|
+
}
|
|
308
559
|
default:
|
|
309
560
|
throw new Error(`Unsupported iMessage content type: ${content.type}`);
|
|
310
561
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-
|
|
1
|
+
import { d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-CfiD_00g.js';
|
|
2
2
|
import * as node_readline from 'node:readline';
|
|
3
3
|
import z__default from 'zod';
|
|
4
4
|
import 'hotscript';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { M as ManagedStream } from '../../stream-DGy4geUK.js';
|
|
2
2
|
import * as z from 'zod';
|
|
3
3
|
import z__default from 'zod';
|
|
4
|
-
import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-
|
|
4
|
+
import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-CfiD_00g.js';
|
|
5
5
|
import * as zod_v4_core from 'zod/v4/core';
|
|
6
6
|
import { WhatsAppClient } from '@photon-ai/whatsapp-business';
|
|
7
7
|
import 'hotscript';
|