@whanext/core 0.17.1 → 0.18.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.
- package/CHANGELOG.md +28 -0
- package/CONTRIBUTING.md +3 -3
- package/MIGRATING_TO_ZAPO.md +73 -0
- package/README.md +9 -7
- package/dist/index.d.ts +2 -1
- package/dist/index.js +727 -817
- package/dist/index.js.map +1 -1
- package/package.json +12 -3
package/dist/index.js
CHANGED
|
@@ -2297,96 +2297,36 @@ var Browser = /* @__PURE__ */ ((Browser2) => {
|
|
|
2297
2297
|
return Browser2;
|
|
2298
2298
|
})(Browser || {});
|
|
2299
2299
|
|
|
2300
|
-
// src/provider/
|
|
2300
|
+
// src/provider/zapo/zapo-provider.ts
|
|
2301
|
+
import { mkdir } from "fs/promises";
|
|
2302
|
+
import { join } from "path";
|
|
2303
|
+
import { createMediaProcessor } from "@zapo-js/media-utils";
|
|
2304
|
+
import { createSqliteStore } from "@zapo-js/store-sqlite";
|
|
2301
2305
|
import {
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
isJidGroup,
|
|
2307
|
-
makeWASocket,
|
|
2308
|
-
proto as proto2,
|
|
2309
|
-
useMultiFileAuthState
|
|
2310
|
-
} from "@whiskeysockets/baileys";
|
|
2311
|
-
|
|
2312
|
-
// src/provider/baileys/baileys-logger.ts
|
|
2313
|
-
function createBaileysLogger(logger) {
|
|
2314
|
-
return {
|
|
2315
|
-
level: logger.level,
|
|
2316
|
-
child(context) {
|
|
2317
|
-
const name = typeof context.class === "string" ? context.class : "internal";
|
|
2318
|
-
return createBaileysLogger(logger.child(name));
|
|
2319
|
-
},
|
|
2320
|
-
trace(value, message) {
|
|
2321
|
-
logger.debug(resolveMessage(value, message, "Provider trace"), safeContext(value));
|
|
2322
|
-
},
|
|
2323
|
-
debug(value, message) {
|
|
2324
|
-
logger.debug(resolveMessage(value, message, "Provider debug"), safeContext(value));
|
|
2325
|
-
},
|
|
2326
|
-
info(value, message) {
|
|
2327
|
-
logger.debug(resolveMessage(value, message, "Provider info"), safeContext(value));
|
|
2328
|
-
},
|
|
2329
|
-
warn(value, message) {
|
|
2330
|
-
logger.warn(resolveMessage(value, message, "Provider warning"), safeContext(value));
|
|
2331
|
-
},
|
|
2332
|
-
error(value, message) {
|
|
2333
|
-
logger.error(resolveMessage(value, message, "Provider error"), safeContext(value));
|
|
2334
|
-
}
|
|
2335
|
-
};
|
|
2336
|
-
}
|
|
2337
|
-
function resolveMessage(value, message, fallback) {
|
|
2338
|
-
if (message) {
|
|
2339
|
-
return message;
|
|
2340
|
-
}
|
|
2341
|
-
return typeof value === "string" ? value : fallback;
|
|
2342
|
-
}
|
|
2343
|
-
function safeContext(value) {
|
|
2344
|
-
if (value instanceof Error) {
|
|
2345
|
-
return { error: value };
|
|
2346
|
-
}
|
|
2347
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2348
|
-
return {};
|
|
2349
|
-
}
|
|
2350
|
-
const source = value;
|
|
2351
|
-
const allowed = [
|
|
2352
|
-
"location",
|
|
2353
|
-
"reason",
|
|
2354
|
-
"status",
|
|
2355
|
-
"statusCode",
|
|
2356
|
-
"type"
|
|
2357
|
-
];
|
|
2358
|
-
return Object.fromEntries(
|
|
2359
|
-
allowed.filter((key) => source[key] !== void 0).map((key) => [key, source[key]])
|
|
2360
|
-
);
|
|
2361
|
-
}
|
|
2306
|
+
WaClient,
|
|
2307
|
+
createStore,
|
|
2308
|
+
proto
|
|
2309
|
+
} from "zapo-js";
|
|
2362
2310
|
|
|
2363
|
-
// src/provider/
|
|
2364
|
-
|
|
2365
|
-
extractMessageContent,
|
|
2366
|
-
getContentType,
|
|
2367
|
-
normalizeMessageContent
|
|
2368
|
-
} from "@whiskeysockets/baileys";
|
|
2369
|
-
function unwrapMessageContent(input) {
|
|
2311
|
+
// src/provider/zapo/normalize-message.ts
|
|
2312
|
+
function unwrapZapoMessageContent(input) {
|
|
2370
2313
|
if (!input) return void 0;
|
|
2371
|
-
const
|
|
2372
|
-
|
|
2373
|
-
if (!content) return void 0;
|
|
2374
|
-
const nested = content.ephemeralMessage?.message ?? content.viewOnceMessage?.message ?? content.viewOnceMessageV2?.message ?? content.viewOnceMessageV2Extension?.message;
|
|
2375
|
-
return nested ? unwrapMessageContent(nested) : content;
|
|
2314
|
+
const nested = input.ephemeralMessage?.message ?? input.viewOnceMessage?.message ?? input.viewOnceMessageV2?.message ?? input.deviceSentMessage?.message ?? input.documentWithCaptionMessage?.message;
|
|
2315
|
+
return nested ? unwrapZapoMessageContent(nested) : input;
|
|
2376
2316
|
}
|
|
2377
|
-
function
|
|
2317
|
+
function isZapoViewOnceContent(input) {
|
|
2378
2318
|
if (!input) return false;
|
|
2379
|
-
if (input.viewOnceMessage?.message || input.viewOnceMessageV2?.message
|
|
2319
|
+
if (input.viewOnceMessage?.message || input.viewOnceMessageV2?.message) {
|
|
2380
2320
|
return true;
|
|
2381
2321
|
}
|
|
2382
|
-
return
|
|
2322
|
+
return isZapoViewOnceContent(input.ephemeralMessage?.message);
|
|
2383
2323
|
}
|
|
2384
|
-
function
|
|
2385
|
-
const
|
|
2386
|
-
const
|
|
2324
|
+
function extractQuotedZapoMessage(input) {
|
|
2325
|
+
const event = input;
|
|
2326
|
+
const chatId = event.key.remoteJid;
|
|
2327
|
+
const content = unwrapZapoMessageContent(event.message);
|
|
2387
2328
|
if (!chatId || !content) return void 0;
|
|
2388
|
-
const
|
|
2389
|
-
const node = type ? content[type] : void 0;
|
|
2329
|
+
const node = contentNode(content);
|
|
2390
2330
|
const context = getContextInfo(node);
|
|
2391
2331
|
if (!context?.stanzaId || !context.quotedMessage) return void 0;
|
|
2392
2332
|
return {
|
|
@@ -2399,26 +2339,25 @@ function extractQuotedBaileysMessage(input) {
|
|
|
2399
2339
|
message: context.quotedMessage
|
|
2400
2340
|
};
|
|
2401
2341
|
}
|
|
2402
|
-
function
|
|
2403
|
-
const
|
|
2404
|
-
const
|
|
2405
|
-
|
|
2342
|
+
function normalizeZapoMessage(input) {
|
|
2343
|
+
const event = input;
|
|
2344
|
+
const chatId = event.key.remoteJid;
|
|
2345
|
+
const id = event.key.id;
|
|
2346
|
+
if (!chatId || !id || !event.message) {
|
|
2406
2347
|
return void 0;
|
|
2407
2348
|
}
|
|
2408
|
-
const content =
|
|
2349
|
+
const content = unwrapZapoMessageContent(event.message);
|
|
2409
2350
|
if (!content) {
|
|
2410
2351
|
return void 0;
|
|
2411
2352
|
}
|
|
2412
|
-
const type =
|
|
2413
|
-
const node = type ? content[type] : void 0;
|
|
2353
|
+
const { type, node } = contentNode(content);
|
|
2414
2354
|
const context = getContextInfo(node);
|
|
2415
|
-
const isPrivateIncoming = !chatId.endsWith("@g.us") &&
|
|
2416
|
-
const remoteJidAlt = input.key.remoteJidAlt;
|
|
2355
|
+
const isPrivateIncoming = !chatId.endsWith("@g.us") && event.key.fromMe !== true;
|
|
2417
2356
|
const senderIds = uniqueIdentities([
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
isPrivateIncoming ? remoteJidAlt : void 0,
|
|
2357
|
+
event.key.participant,
|
|
2358
|
+
event.key.participantAlt,
|
|
2359
|
+
event.key.senderUsername?.includes("@") ? event.key.senderUsername : void 0,
|
|
2360
|
+
isPrivateIncoming ? event.key.remoteJidAlt : void 0,
|
|
2422
2361
|
isPrivateIncoming ? chatId : void 0
|
|
2423
2362
|
]);
|
|
2424
2363
|
const senderJid = senderIds.find((identity) => identity.endsWith("@s.whatsapp.net") || identity.endsWith("@c.us"));
|
|
@@ -2427,10 +2366,11 @@ function normalizeBaileysMessage(input) {
|
|
|
2427
2366
|
const sender = new User({
|
|
2428
2367
|
id: senderId,
|
|
2429
2368
|
identities: senderIds.length > 0 ? senderIds : [senderId],
|
|
2430
|
-
...
|
|
2369
|
+
...event.pushName ? { name: event.pushName } : {}
|
|
2431
2370
|
});
|
|
2432
|
-
const
|
|
2433
|
-
const
|
|
2371
|
+
const mentionedIds = [...context?.mentionedJid ?? []];
|
|
2372
|
+
const mentionedUsers = mentionedIds.map((identity) => User.fromIdentities([identity]));
|
|
2373
|
+
const viewOnce = isZapoViewOnceContent(event.message);
|
|
2434
2374
|
const media = getMedia(type, node, viewOnce);
|
|
2435
2375
|
const contentKind = getContentKind(type);
|
|
2436
2376
|
const text = getText(content);
|
|
@@ -2443,10 +2383,10 @@ function normalizeBaileysMessage(input) {
|
|
|
2443
2383
|
senderId,
|
|
2444
2384
|
senderIds: senderIds.length > 0 ? senderIds : [senderId],
|
|
2445
2385
|
sender,
|
|
2446
|
-
keys:
|
|
2447
|
-
mentions:
|
|
2386
|
+
keys: normalizeZapoKey(event.key),
|
|
2387
|
+
mentions: mentionedIds,
|
|
2448
2388
|
mentionedUsers,
|
|
2449
|
-
timestamp: toDate(
|
|
2389
|
+
timestamp: toDate(event.timestampSeconds),
|
|
2450
2390
|
isGroup: chatId.endsWith("@g.us"),
|
|
2451
2391
|
isReply: quoted !== void 0,
|
|
2452
2392
|
isViewOnce: media?.viewOnce ?? false,
|
|
@@ -2464,6 +2404,45 @@ function normalizeBaileysMessage(input) {
|
|
|
2464
2404
|
if (quoted !== void 0) message.quoted = quoted;
|
|
2465
2405
|
return message;
|
|
2466
2406
|
}
|
|
2407
|
+
function normalizeZapoKey(key) {
|
|
2408
|
+
const normalized = {
|
|
2409
|
+
id: key.id ?? "",
|
|
2410
|
+
chatId: key.remoteJid ?? "",
|
|
2411
|
+
fromMe: key.fromMe ?? false
|
|
2412
|
+
};
|
|
2413
|
+
const participantId = key.participant ?? key.participantAlt;
|
|
2414
|
+
if (participantId !== null && participantId !== void 0) {
|
|
2415
|
+
normalized.participantId = participantId;
|
|
2416
|
+
}
|
|
2417
|
+
return normalized;
|
|
2418
|
+
}
|
|
2419
|
+
function contentNode(content) {
|
|
2420
|
+
const order = [
|
|
2421
|
+
"conversation",
|
|
2422
|
+
"extendedTextMessage",
|
|
2423
|
+
"imageMessage",
|
|
2424
|
+
"videoMessage",
|
|
2425
|
+
"audioMessage",
|
|
2426
|
+
"documentMessage",
|
|
2427
|
+
"stickerMessage",
|
|
2428
|
+
"locationMessage",
|
|
2429
|
+
"liveLocationMessage",
|
|
2430
|
+
"contactMessage",
|
|
2431
|
+
"contactsArrayMessage",
|
|
2432
|
+
"buttonsResponseMessage",
|
|
2433
|
+
"listResponseMessage",
|
|
2434
|
+
"templateButtonReplyMessage",
|
|
2435
|
+
"pollCreationMessage",
|
|
2436
|
+
"pollCreationMessageV2",
|
|
2437
|
+
"pollCreationMessageV3",
|
|
2438
|
+
"pollCreationMessageV5",
|
|
2439
|
+
"productMessage",
|
|
2440
|
+
"orderMessage",
|
|
2441
|
+
"interactiveResponseMessage"
|
|
2442
|
+
];
|
|
2443
|
+
const type = order.find((key) => content[key] !== null && content[key] !== void 0);
|
|
2444
|
+
return { type, node: type ? content[type] : void 0 };
|
|
2445
|
+
}
|
|
2467
2446
|
function getContentKind(type) {
|
|
2468
2447
|
switch (String(type ?? "")) {
|
|
2469
2448
|
case "conversation":
|
|
@@ -2471,6 +2450,7 @@ function getContentKind(type) {
|
|
|
2471
2450
|
case "buttonsResponseMessage":
|
|
2472
2451
|
case "listResponseMessage":
|
|
2473
2452
|
case "templateButtonReplyMessage":
|
|
2453
|
+
case "interactiveResponseMessage":
|
|
2474
2454
|
return "text";
|
|
2475
2455
|
case "imageMessage":
|
|
2476
2456
|
return "image";
|
|
@@ -2479,7 +2459,6 @@ function getContentKind(type) {
|
|
|
2479
2459
|
case "audioMessage":
|
|
2480
2460
|
return "audio";
|
|
2481
2461
|
case "documentMessage":
|
|
2482
|
-
case "documentWithCaptionMessage":
|
|
2483
2462
|
return "document";
|
|
2484
2463
|
case "stickerMessage":
|
|
2485
2464
|
return "sticker";
|
|
@@ -2492,6 +2471,7 @@ function getContentKind(type) {
|
|
|
2492
2471
|
case "pollCreationMessage":
|
|
2493
2472
|
case "pollCreationMessageV2":
|
|
2494
2473
|
case "pollCreationMessageV3":
|
|
2474
|
+
case "pollCreationMessageV5":
|
|
2495
2475
|
return "poll";
|
|
2496
2476
|
case "productMessage":
|
|
2497
2477
|
case "orderMessage":
|
|
@@ -2500,20 +2480,8 @@ function getContentKind(type) {
|
|
|
2500
2480
|
return "unknown";
|
|
2501
2481
|
}
|
|
2502
2482
|
}
|
|
2503
|
-
function normalizeKey(key) {
|
|
2504
|
-
const normalized = {
|
|
2505
|
-
id: key.id ?? "",
|
|
2506
|
-
chatId: key.remoteJid ?? "",
|
|
2507
|
-
fromMe: key.fromMe ?? false
|
|
2508
|
-
};
|
|
2509
|
-
const participantId = key.participant ?? key.participantAlt;
|
|
2510
|
-
if (participantId !== null && participantId !== void 0) {
|
|
2511
|
-
normalized.participantId = participantId;
|
|
2512
|
-
}
|
|
2513
|
-
return normalized;
|
|
2514
|
-
}
|
|
2515
2483
|
function getText(content) {
|
|
2516
|
-
return content.conversation ?? content.extendedTextMessage?.text ?? content.buttonsResponseMessage?.selectedDisplayText ?? content.listResponseMessage?.title ?? void 0;
|
|
2484
|
+
return content.conversation ?? content.extendedTextMessage?.text ?? content.buttonsResponseMessage?.selectedDisplayText ?? content.listResponseMessage?.title ?? content.templateButtonReplyMessage?.selectedDisplayText ?? void 0;
|
|
2517
2485
|
}
|
|
2518
2486
|
function getCaption(content) {
|
|
2519
2487
|
return content.imageMessage?.caption ?? content.videoMessage?.caption ?? content.documentMessage?.caption ?? void 0;
|
|
@@ -2522,9 +2490,9 @@ function getContextInfo(node) {
|
|
|
2522
2490
|
if (typeof node !== "object" || node === null || !("contextInfo" in node)) {
|
|
2523
2491
|
return void 0;
|
|
2524
2492
|
}
|
|
2525
|
-
return node.contextInfo;
|
|
2493
|
+
return node.contextInfo ?? void 0;
|
|
2526
2494
|
}
|
|
2527
|
-
function getMedia(type, node,
|
|
2495
|
+
function getMedia(type, node, wrapperViewOnce) {
|
|
2528
2496
|
const mapping = {
|
|
2529
2497
|
imageMessage: "image",
|
|
2530
2498
|
videoMessage: "video",
|
|
@@ -2539,307 +2507,112 @@ function getMedia(type, node, keyViewOnce) {
|
|
|
2539
2507
|
const value = node;
|
|
2540
2508
|
const media = {
|
|
2541
2509
|
kind,
|
|
2542
|
-
viewOnce:
|
|
2510
|
+
viewOnce: wrapperViewOnce || value.viewOnce === true
|
|
2543
2511
|
};
|
|
2544
2512
|
if (value.mimetype) media.mimetype = value.mimetype;
|
|
2545
2513
|
if (value.fileName) media.fileName = value.fileName;
|
|
2546
|
-
|
|
2514
|
+
const seconds = toNumber(value.seconds);
|
|
2515
|
+
if (seconds !== void 0) media.seconds = seconds;
|
|
2547
2516
|
return media;
|
|
2548
2517
|
}
|
|
2549
2518
|
function getQuoted(context, chatId) {
|
|
2550
|
-
if (!context?.stanzaId)
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
const
|
|
2554
|
-
const
|
|
2555
|
-
const
|
|
2556
|
-
const
|
|
2557
|
-
const node = type && content ? content[type] : void 0;
|
|
2558
|
-
const media = getMedia(type, node, quotedIsViewOnce);
|
|
2559
|
-
const result = {
|
|
2519
|
+
if (!context?.stanzaId || !context.quotedMessage) return void 0;
|
|
2520
|
+
const content = unwrapZapoMessageContent(context.quotedMessage);
|
|
2521
|
+
if (!content) return void 0;
|
|
2522
|
+
const { type, node } = contentNode(content);
|
|
2523
|
+
const media = getMedia(type, node, isZapoViewOnceContent(context.quotedMessage));
|
|
2524
|
+
const senderId = context.participant ?? void 0;
|
|
2525
|
+
const quoted = {
|
|
2560
2526
|
key: {
|
|
2561
2527
|
id: context.stanzaId,
|
|
2562
2528
|
chatId: context.remoteJid ?? chatId,
|
|
2563
|
-
fromMe: false
|
|
2529
|
+
fromMe: false,
|
|
2530
|
+
...senderId ? { participantId: senderId } : {}
|
|
2564
2531
|
},
|
|
2565
2532
|
hasMedia: media !== void 0,
|
|
2566
|
-
isViewOnce: media?.viewOnce ??
|
|
2533
|
+
isViewOnce: media?.viewOnce ?? false,
|
|
2534
|
+
contentKind: getContentKind(type)
|
|
2567
2535
|
};
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
}
|
|
2574
|
-
if (
|
|
2575
|
-
|
|
2576
|
-
result.sender = User.fromIdentities([context.participant]);
|
|
2577
|
-
result.key.participantId = context.participant;
|
|
2578
|
-
}
|
|
2579
|
-
if (content) {
|
|
2580
|
-
const text = getText(content) ?? getCaption(content);
|
|
2581
|
-
if (text !== void 0) result.text = text;
|
|
2582
|
-
}
|
|
2583
|
-
return result;
|
|
2536
|
+
const text = getText(content) ?? getCaption(content);
|
|
2537
|
+
if (text !== void 0) quoted.text = text;
|
|
2538
|
+
if (senderId !== void 0) {
|
|
2539
|
+
quoted.senderId = senderId;
|
|
2540
|
+
quoted.sender = User.fromIdentities([senderId]);
|
|
2541
|
+
}
|
|
2542
|
+
if (media !== void 0) quoted.media = media;
|
|
2543
|
+
return quoted;
|
|
2584
2544
|
}
|
|
2585
2545
|
function toDate(value) {
|
|
2586
|
-
const seconds = value
|
|
2546
|
+
const seconds = toNumber(value) ?? Math.floor(Date.now() / 1e3);
|
|
2587
2547
|
return new Date(seconds * 1e3);
|
|
2588
2548
|
}
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
jidNormalizedUser,
|
|
2594
|
-
normalizeMessageContent as normalizeMessageContent2,
|
|
2595
|
-
proto
|
|
2596
|
-
} from "@whiskeysockets/baileys";
|
|
2597
|
-
function isSecretEncryptedEdit(message) {
|
|
2598
|
-
const content = normalizeMessageContent2(message.message);
|
|
2599
|
-
return content?.secretEncryptedMessage?.secretEncType === proto.Message.SecretEncryptedMessage.SecretEncType.MESSAGE_EDIT;
|
|
2600
|
-
}
|
|
2601
|
-
function secretEditTargetKey(message) {
|
|
2602
|
-
const content = normalizeMessageContent2(message.message);
|
|
2603
|
-
const secret = content?.secretEncryptedMessage;
|
|
2604
|
-
if (secret?.secretEncType !== proto.Message.SecretEncryptedMessage.SecretEncType.MESSAGE_EDIT || !secret.targetMessageKey?.id) {
|
|
2605
|
-
return void 0;
|
|
2606
|
-
}
|
|
2607
|
-
return secret.targetMessageKey;
|
|
2608
|
-
}
|
|
2609
|
-
function decryptSecretEncryptedEdit(envelope, original, meId, meLid) {
|
|
2610
|
-
const content = normalizeMessageContent2(envelope.message);
|
|
2611
|
-
const secret = content?.secretEncryptedMessage;
|
|
2612
|
-
const targetKey = secret?.targetMessageKey;
|
|
2613
|
-
if (secret?.secretEncType !== proto.Message.SecretEncryptedMessage.SecretEncType.MESSAGE_EDIT || !targetKey?.id || !secret.encPayload?.length || secret.encIv?.length !== 12) {
|
|
2614
|
-
return void 0;
|
|
2615
|
-
}
|
|
2616
|
-
const messageSecret = findMessageSecret(original.message);
|
|
2617
|
-
if (messageSecret?.length !== 32) {
|
|
2618
|
-
return void 0;
|
|
2619
|
-
}
|
|
2620
|
-
const editorCandidates = envelope.key.fromMe ? uniqueUserJids([meId, meLid]) : uniqueUserJids([
|
|
2621
|
-
envelope.key.participant,
|
|
2622
|
-
envelope.key.participantAlt,
|
|
2623
|
-
envelope.key.remoteJid,
|
|
2624
|
-
envelope.key.remoteJidAlt
|
|
2625
|
-
]);
|
|
2626
|
-
const originalSenderCandidates = targetKey.fromMe ? editorCandidates : isUserJid(envelope.key.remoteJid) ? uniqueUserJids([
|
|
2627
|
-
targetKey.remoteJid,
|
|
2628
|
-
targetKey.remoteJidAlt,
|
|
2629
|
-
original.key.remoteJid,
|
|
2630
|
-
original.key.remoteJidAlt
|
|
2631
|
-
]) : uniqueUserJids([
|
|
2632
|
-
targetKey.participant,
|
|
2633
|
-
targetKey.participantAlt,
|
|
2634
|
-
original.key.participant,
|
|
2635
|
-
original.key.participantAlt
|
|
2636
|
-
]);
|
|
2637
|
-
const fallbackOriginalCandidates = original.key.fromMe ? uniqueUserJids([meId, meLid]) : uniqueUserJids([
|
|
2638
|
-
original.key.participant,
|
|
2639
|
-
original.key.participantAlt,
|
|
2640
|
-
original.key.remoteJid,
|
|
2641
|
-
original.key.remoteJidAlt
|
|
2642
|
-
]);
|
|
2643
|
-
const senders = uniqueUserJids([
|
|
2644
|
-
...originalSenderCandidates,
|
|
2645
|
-
...fallbackOriginalCandidates
|
|
2646
|
-
]);
|
|
2647
|
-
if (!editorCandidates.length || !senders.length) {
|
|
2648
|
-
return void 0;
|
|
2649
|
-
}
|
|
2650
|
-
let decoded;
|
|
2651
|
-
for (const originalSender of senders) {
|
|
2652
|
-
for (const editor of editorCandidates) {
|
|
2653
|
-
try {
|
|
2654
|
-
decoded = decryptPayload(
|
|
2655
|
-
targetKey.id,
|
|
2656
|
-
originalSender,
|
|
2657
|
-
editor,
|
|
2658
|
-
messageSecret,
|
|
2659
|
-
secret.encIv,
|
|
2660
|
-
secret.encPayload
|
|
2661
|
-
);
|
|
2662
|
-
break;
|
|
2663
|
-
} catch {
|
|
2664
|
-
continue;
|
|
2665
|
-
}
|
|
2666
|
-
}
|
|
2667
|
-
if (decoded) {
|
|
2668
|
-
break;
|
|
2669
|
-
}
|
|
2670
|
-
}
|
|
2671
|
-
const protocol = decoded?.protocolMessage;
|
|
2672
|
-
if (protocol?.type !== proto.Message.ProtocolMessage.Type.MESSAGE_EDIT || !protocol.editedMessage || protocol.key?.id && protocol.key.id !== targetKey.id) {
|
|
2673
|
-
return void 0;
|
|
2674
|
-
}
|
|
2675
|
-
const edited = protocol.editedMessage;
|
|
2676
|
-
if (!edited.messageContextInfo?.messageSecret?.length) {
|
|
2677
|
-
edited.messageContextInfo = {
|
|
2678
|
-
...edited.messageContextInfo,
|
|
2679
|
-
messageSecret
|
|
2680
|
-
};
|
|
2681
|
-
}
|
|
2682
|
-
return {
|
|
2683
|
-
message: edited,
|
|
2684
|
-
...protocol.timestampMs ? { timestamp: Math.floor(numberValue(protocol.timestampMs) / 1e3) } : {}
|
|
2685
|
-
};
|
|
2686
|
-
}
|
|
2687
|
-
function decryptPayload(messageId, originalSender, editor, messageSecret, iv, payload) {
|
|
2688
|
-
const info = Buffer.concat([
|
|
2689
|
-
Buffer.from(messageId, "utf8"),
|
|
2690
|
-
Buffer.from(originalSender, "utf8"),
|
|
2691
|
-
Buffer.from(editor, "utf8"),
|
|
2692
|
-
Buffer.from("Message Edit", "utf8")
|
|
2693
|
-
]);
|
|
2694
|
-
const key = Buffer.from(hkdfSync(
|
|
2695
|
-
"sha256",
|
|
2696
|
-
Buffer.from(messageSecret),
|
|
2697
|
-
Buffer.alloc(32),
|
|
2698
|
-
info,
|
|
2699
|
-
32
|
|
2700
|
-
));
|
|
2701
|
-
const encrypted = Buffer.from(payload);
|
|
2702
|
-
if (encrypted.length <= 16) {
|
|
2703
|
-
throw new Error("INVALID_EDIT_PAYLOAD");
|
|
2704
|
-
}
|
|
2705
|
-
const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(iv));
|
|
2706
|
-
decipher.setAAD(Buffer.alloc(0));
|
|
2707
|
-
decipher.setAuthTag(encrypted.subarray(encrypted.length - 16));
|
|
2708
|
-
return proto.Message.decode(Buffer.concat([
|
|
2709
|
-
decipher.update(encrypted.subarray(0, encrypted.length - 16)),
|
|
2710
|
-
decipher.final()
|
|
2711
|
-
]));
|
|
2712
|
-
}
|
|
2713
|
-
function findMessageSecret(message) {
|
|
2714
|
-
if (!message) {
|
|
2715
|
-
return void 0;
|
|
2716
|
-
}
|
|
2717
|
-
const direct = message.messageContextInfo?.messageSecret;
|
|
2718
|
-
if (direct?.length) {
|
|
2719
|
-
return direct;
|
|
2720
|
-
}
|
|
2721
|
-
const normalized = normalizeMessageContent2(message);
|
|
2722
|
-
const normalizedSecret = normalized?.messageContextInfo?.messageSecret;
|
|
2723
|
-
if (normalizedSecret?.length) {
|
|
2724
|
-
return normalizedSecret;
|
|
2725
|
-
}
|
|
2726
|
-
const deviceSecret = message.deviceSentMessage?.message?.messageContextInfo?.messageSecret;
|
|
2727
|
-
if (deviceSecret?.length) {
|
|
2728
|
-
return deviceSecret;
|
|
2729
|
-
}
|
|
2549
|
+
function toNumber(value) {
|
|
2550
|
+
if (typeof value === "number") return value;
|
|
2551
|
+
if (value?.toNumber) return value.toNumber();
|
|
2552
|
+
if (typeof value?.low === "number") return value.low;
|
|
2730
2553
|
return void 0;
|
|
2731
2554
|
}
|
|
2732
|
-
function uniqueUserJids(values) {
|
|
2733
|
-
return [...new Set(
|
|
2734
|
-
values.map(normalizeUserJid).filter((value) => value !== void 0)
|
|
2735
|
-
)];
|
|
2736
|
-
}
|
|
2737
|
-
function normalizeUserJid(value) {
|
|
2738
|
-
if (!isUserJid(value)) {
|
|
2739
|
-
return void 0;
|
|
2740
|
-
}
|
|
2741
|
-
return jidNormalizedUser(value);
|
|
2742
|
-
}
|
|
2743
|
-
function isUserJid(value) {
|
|
2744
|
-
if (!value) {
|
|
2745
|
-
return false;
|
|
2746
|
-
}
|
|
2747
|
-
const normalized = jidNormalizedUser(value);
|
|
2748
|
-
return normalized.endsWith("@s.whatsapp.net") || normalized.endsWith("@lid") || normalized.endsWith("@hosted") || normalized.endsWith("@hosted.lid");
|
|
2749
|
-
}
|
|
2750
|
-
function numberValue(value) {
|
|
2751
|
-
if (typeof value === "number") {
|
|
2752
|
-
return value;
|
|
2753
|
-
}
|
|
2754
|
-
if (typeof value === "bigint") {
|
|
2755
|
-
return Number(value);
|
|
2756
|
-
}
|
|
2757
|
-
if (value && typeof value === "object" && "toString" in value) {
|
|
2758
|
-
return Number(String(value));
|
|
2759
|
-
}
|
|
2760
|
-
return Number(value);
|
|
2761
|
-
}
|
|
2762
2555
|
|
|
2763
|
-
// src/provider/
|
|
2764
|
-
var
|
|
2556
|
+
// src/provider/zapo/zapo-provider.ts
|
|
2557
|
+
var ZapoProvider = class {
|
|
2765
2558
|
#options;
|
|
2766
2559
|
#events = new TypedEventEmitter();
|
|
2767
2560
|
#logger;
|
|
2768
2561
|
#messageStore = /* @__PURE__ */ new Map();
|
|
2769
2562
|
#messageCacheSize;
|
|
2770
|
-
#
|
|
2771
|
-
#
|
|
2772
|
-
#groupMetadataGenerations = /* @__PURE__ */ new Map();
|
|
2773
|
-
#groupMetadataCacheEnabled;
|
|
2774
|
-
#groupMetadataCacheTtlMs;
|
|
2775
|
-
#groupMetadataCacheSize;
|
|
2776
|
-
#socket;
|
|
2777
|
-
#saveCredentials;
|
|
2778
|
-
#saveQueue = Promise.resolve();
|
|
2563
|
+
#client;
|
|
2564
|
+
#voip;
|
|
2779
2565
|
#intentionalClose = false;
|
|
2780
2566
|
#reconnectAttempt = 0;
|
|
2781
2567
|
#reconnectTimer;
|
|
2782
|
-
#
|
|
2568
|
+
#connectPromise;
|
|
2569
|
+
#pairingRequired = false;
|
|
2570
|
+
#connected = false;
|
|
2571
|
+
#connectedAtSeconds = 0;
|
|
2572
|
+
#pairingReady = Promise.resolve();
|
|
2573
|
+
#resolvePairingReady;
|
|
2783
2574
|
constructor(options) {
|
|
2784
2575
|
this.#options = options;
|
|
2785
2576
|
this.#logger = options.logger ?? new Logger("silent");
|
|
2786
2577
|
this.#messageCacheSize = Math.max(1, options.messageCacheSize ?? 1e3);
|
|
2787
|
-
this.#groupMetadataCacheEnabled = options.groupMetadataCache?.enabled !== false;
|
|
2788
|
-
this.#groupMetadataCacheTtlMs = Math.max(1, options.groupMetadataCache?.ttlMs ?? 3e5);
|
|
2789
|
-
this.#groupMetadataCacheSize = Math.max(1, options.groupMetadataCache?.maxEntries ?? 1e3);
|
|
2790
2578
|
}
|
|
2791
2579
|
on(event, listener) {
|
|
2792
2580
|
return this.#events.on(event, listener);
|
|
2793
2581
|
}
|
|
2794
2582
|
async connect() {
|
|
2795
|
-
|
|
2583
|
+
this.#intentionalClose = false;
|
|
2584
|
+
const client = await this.#ensureClient();
|
|
2585
|
+
if (this.#connected || this.#connectPromise) {
|
|
2796
2586
|
return;
|
|
2797
2587
|
}
|
|
2798
|
-
this.#
|
|
2588
|
+
this.#preparePairingGate();
|
|
2799
2589
|
await this.#events.emit("connection", {
|
|
2800
2590
|
state: this.#reconnectAttempt > 0 ? "reconnecting" : "connecting",
|
|
2801
2591
|
attempt: this.#reconnectAttempt
|
|
2802
2592
|
});
|
|
2803
|
-
|
|
2804
|
-
const { state, saveCreds } = await useMultiFileAuthState(this.#options.auth);
|
|
2805
|
-
this.#registered = state.creds.registered;
|
|
2806
|
-
this.#saveCredentials = saveCreds;
|
|
2807
|
-
const socket = makeWASocket({
|
|
2808
|
-
auth: state,
|
|
2809
|
-
browser: this.#browserDescription(),
|
|
2810
|
-
logger: createBaileysLogger(this.#logger.child("baileys")),
|
|
2811
|
-
markOnlineOnConnect: false,
|
|
2812
|
-
enableAutoSessionRecreation: true,
|
|
2813
|
-
enableRecentMessageCache: true,
|
|
2814
|
-
cachedGroupMetadata: async (jid) => this.#getGroupMetadata(jid),
|
|
2815
|
-
getMessage: async (key) => this.#messageStore.get(this.#messageStoreKey(key))?.message ?? void 0
|
|
2816
|
-
});
|
|
2817
|
-
this.#socket = socket;
|
|
2818
|
-
this.#bind(socket);
|
|
2819
|
-
} catch (error) {
|
|
2820
|
-
this.#socket = void 0;
|
|
2821
|
-
throw new WhaNextError("CONNECTION_FAILED", "Could not start the WhatsApp connection.", {
|
|
2822
|
-
cause: error,
|
|
2823
|
-
recoverable: true
|
|
2824
|
-
});
|
|
2825
|
-
}
|
|
2593
|
+
this.#startConnect(client);
|
|
2826
2594
|
}
|
|
2827
2595
|
async disconnect() {
|
|
2828
2596
|
this.#intentionalClose = true;
|
|
2829
|
-
if (this.#reconnectTimer)
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2597
|
+
if (this.#reconnectTimer) {
|
|
2598
|
+
clearTimeout(this.#reconnectTimer);
|
|
2599
|
+
this.#reconnectTimer = void 0;
|
|
2600
|
+
}
|
|
2601
|
+
const client = this.#client;
|
|
2602
|
+
this.#connectPromise = void 0;
|
|
2603
|
+
if (client) {
|
|
2604
|
+
await client.disconnect();
|
|
2605
|
+
} else {
|
|
2606
|
+
await this.#events.emit("connection", { state: "closed" });
|
|
2834
2607
|
}
|
|
2835
|
-
|
|
2608
|
+
this.#connected = false;
|
|
2836
2609
|
}
|
|
2837
2610
|
getCurrentUserIds() {
|
|
2838
|
-
const
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2611
|
+
const credentials = this.#client?.getCredentials();
|
|
2612
|
+
return uniqueIdentities([
|
|
2613
|
+
credentials?.meJid,
|
|
2614
|
+
credentials?.meLid
|
|
2615
|
+
]);
|
|
2843
2616
|
}
|
|
2844
2617
|
async requestPairingCode(phone) {
|
|
2845
2618
|
const normalized = phone.replace(/\D/g, "");
|
|
@@ -2849,34 +2622,28 @@ var BaileysProvider = class {
|
|
|
2849
2622
|
"The phone number must include its country code."
|
|
2850
2623
|
);
|
|
2851
2624
|
}
|
|
2852
|
-
|
|
2625
|
+
const client = await this.#ensureClient();
|
|
2626
|
+
if (client.getCredentials()?.meJid) {
|
|
2853
2627
|
return "";
|
|
2854
2628
|
}
|
|
2855
|
-
|
|
2629
|
+
if (!this.#connectPromise && !this.#connected) {
|
|
2630
|
+
await this.connect();
|
|
2631
|
+
}
|
|
2856
2632
|
try {
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
"The WhatsApp
|
|
2862
|
-
{
|
|
2863
|
-
recoverable: true
|
|
2864
|
-
}
|
|
2633
|
+
if (!this.#pairingRequired) {
|
|
2634
|
+
await this.#withTimeout(
|
|
2635
|
+
this.#pairingReady,
|
|
2636
|
+
6e4,
|
|
2637
|
+
"The WhatsApp pairing challenge was not received in time."
|
|
2865
2638
|
);
|
|
2866
2639
|
}
|
|
2867
|
-
return await
|
|
2640
|
+
return await client.auth.requestPairingCode(normalized);
|
|
2868
2641
|
} catch (error) {
|
|
2869
|
-
if (error instanceof WhaNextError)
|
|
2870
|
-
throw error;
|
|
2871
|
-
}
|
|
2642
|
+
if (error instanceof WhaNextError) throw error;
|
|
2872
2643
|
throw new WhaNextError(
|
|
2873
2644
|
"CONNECTION_FAILED",
|
|
2874
2645
|
"Could not request the pairing code after the authentication challenge.",
|
|
2875
|
-
{
|
|
2876
|
-
cause: error,
|
|
2877
|
-
context: { statusCode: this.#statusCode(error) },
|
|
2878
|
-
recoverable: this.#statusCode(error) === DisconnectReason.connectionClosed
|
|
2879
|
-
}
|
|
2646
|
+
{ cause: error, recoverable: true }
|
|
2880
2647
|
);
|
|
2881
2648
|
}
|
|
2882
2649
|
}
|
|
@@ -2884,18 +2651,17 @@ var BaileysProvider = class {
|
|
|
2884
2651
|
if ("buttons" in content) {
|
|
2885
2652
|
return this.#sendButtons(chatId, content, replyTo);
|
|
2886
2653
|
}
|
|
2887
|
-
const
|
|
2888
|
-
const
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
}
|
|
2893
|
-
}
|
|
2894
|
-
|
|
2895
|
-
return this.#sent(result);
|
|
2654
|
+
const client = this.#requireClient();
|
|
2655
|
+
const { value, mentions, viewOnce } = await this.#toContent(content);
|
|
2656
|
+
const result = await client.message.send(chatId, value, {
|
|
2657
|
+
...replyTo ? { quote: this.#toZapoKey(replyTo) } : {},
|
|
2658
|
+
...mentions.length > 0 ? { mentions } : {},
|
|
2659
|
+
...viewOnce !== void 0 ? { viewOnce } : {}
|
|
2660
|
+
});
|
|
2661
|
+
return this.#sent(result, chatId);
|
|
2896
2662
|
}
|
|
2897
2663
|
async repostMessage(source, chatId, options = {}) {
|
|
2898
|
-
const original = this.#
|
|
2664
|
+
const original = this.#findStoredMessage(this.#toZapoKey(source));
|
|
2899
2665
|
if (!original?.message) {
|
|
2900
2666
|
throw new WhaNextError(
|
|
2901
2667
|
"MESSAGE_NOT_FOUND",
|
|
@@ -2906,24 +2672,26 @@ var BaileysProvider = class {
|
|
|
2906
2672
|
}
|
|
2907
2673
|
);
|
|
2908
2674
|
}
|
|
2909
|
-
const
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2675
|
+
const result = await this.#requireClient().message.send(
|
|
2676
|
+
chatId,
|
|
2677
|
+
original.message,
|
|
2678
|
+
{
|
|
2679
|
+
forward: true,
|
|
2680
|
+
...options.mentions && options.mentions.length > 0 ? { mentions: this.#mentions(options.mentions) } : {}
|
|
2681
|
+
}
|
|
2682
|
+
);
|
|
2683
|
+
return this.#sent(result, chatId);
|
|
2915
2684
|
}
|
|
2916
2685
|
async reactToMessage(key, emoji) {
|
|
2917
|
-
const result = await this.#
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
}
|
|
2686
|
+
const result = await this.#requireClient().message.send(key.chatId, {
|
|
2687
|
+
type: "reaction",
|
|
2688
|
+
emoji: emoji ?? "",
|
|
2689
|
+
target: this.#toZapoKey(key)
|
|
2922
2690
|
});
|
|
2923
|
-
return this.#sent(result);
|
|
2691
|
+
return this.#sent(result, key.chatId);
|
|
2924
2692
|
}
|
|
2925
2693
|
async downloadMedia(key) {
|
|
2926
|
-
const message = this.#
|
|
2694
|
+
const message = this.#findStoredMessage(this.#toZapoKey(key));
|
|
2927
2695
|
if (!message?.message) {
|
|
2928
2696
|
throw new WhaNextError(
|
|
2929
2697
|
"MEDIA_NOT_AVAILABLE",
|
|
@@ -2931,54 +2699,75 @@ var BaileysProvider = class {
|
|
|
2931
2699
|
{ recoverable: true }
|
|
2932
2700
|
);
|
|
2933
2701
|
}
|
|
2934
|
-
const
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2702
|
+
const normalized = normalizeZapoMessage(message);
|
|
2703
|
+
if (!normalized?.media) {
|
|
2704
|
+
throw new WhaNextError(
|
|
2705
|
+
"MEDIA_NOT_AVAILABLE",
|
|
2706
|
+
"The selected message does not contain media."
|
|
2707
|
+
);
|
|
2708
|
+
}
|
|
2709
|
+
try {
|
|
2710
|
+
const bytes = await this.#requireClient().message.downloadBytes(
|
|
2711
|
+
message
|
|
2712
|
+
);
|
|
2713
|
+
return {
|
|
2714
|
+
data: Buffer.from(bytes),
|
|
2715
|
+
kind: normalized.media.kind,
|
|
2716
|
+
...normalized.media.mimetype ? { mimetype: normalized.media.mimetype } : {},
|
|
2717
|
+
...normalized.media.fileName ? { fileName: normalized.media.fileName } : {}
|
|
2718
|
+
};
|
|
2719
|
+
} catch (error) {
|
|
2720
|
+
throw new WhaNextError(
|
|
2721
|
+
"MEDIA_NOT_AVAILABLE",
|
|
2722
|
+
"WhatsApp could not download the selected media.",
|
|
2723
|
+
{ cause: error, recoverable: true }
|
|
2724
|
+
);
|
|
2941
2725
|
}
|
|
2942
|
-
return {
|
|
2943
|
-
data,
|
|
2944
|
-
kind: media.kind,
|
|
2945
|
-
...media.mimetype ? { mimetype: media.mimetype } : {},
|
|
2946
|
-
...media.fileName ? { fileName: media.fileName } : {}
|
|
2947
|
-
};
|
|
2948
2726
|
}
|
|
2949
2727
|
async editMessage(key, content) {
|
|
2950
|
-
const result = await this.#
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2728
|
+
const result = await this.#requireClient().message.send(
|
|
2729
|
+
key.chatId,
|
|
2730
|
+
content,
|
|
2731
|
+
{ editKey: this.#toZapoKey(key) }
|
|
2732
|
+
);
|
|
2733
|
+
return this.#sent(result, key.chatId);
|
|
2955
2734
|
}
|
|
2956
2735
|
async deleteMessage(key) {
|
|
2957
|
-
await this.#
|
|
2736
|
+
await this.#requireClient().message.send(key.chatId, {
|
|
2737
|
+
type: "revoke",
|
|
2738
|
+
target: this.#toZapoKey(key)
|
|
2739
|
+
});
|
|
2958
2740
|
}
|
|
2959
2741
|
async getGroup(groupId) {
|
|
2960
|
-
const metadata = await this.#
|
|
2742
|
+
const metadata = await this.#requireClient().group.queryGroupMetadata(groupId);
|
|
2743
|
+
const participants = [...metadata.participants ?? []];
|
|
2744
|
+
const addressingMode = metadata.addressingMode === "lid" || participants.some((participant) => (participant.jid ?? participant.id ?? "").endsWith("@lid")) ? "lid" : "pn";
|
|
2961
2745
|
return {
|
|
2962
|
-
id: metadata.id,
|
|
2963
|
-
subject: metadata.subject,
|
|
2746
|
+
id: metadata.jid ?? metadata.id ?? groupId,
|
|
2747
|
+
subject: metadata.subject ?? "",
|
|
2964
2748
|
access: metadata.announce ? "closed" : "open",
|
|
2965
|
-
addressingMode
|
|
2749
|
+
addressingMode,
|
|
2966
2750
|
fetchedAt: /* @__PURE__ */ new Date(),
|
|
2967
|
-
participants:
|
|
2968
|
-
id
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2751
|
+
participants: participants.map((participant) => {
|
|
2752
|
+
const id = participant.jid ?? participant.id ?? participant.lid ?? participant.phoneNumber ?? "";
|
|
2753
|
+
return {
|
|
2754
|
+
id,
|
|
2755
|
+
...participant.lid ? { lid: participant.lid } : {},
|
|
2756
|
+
...participant.phoneNumber ? { phoneNumber: participant.phoneNumber } : {},
|
|
2757
|
+
role: participant.isSuperAdmin || participant.admin === "superadmin" ? "owner" : participant.isAdmin || participant.admin === "admin" ? "admin" : "member"
|
|
2758
|
+
};
|
|
2759
|
+
})
|
|
2973
2760
|
};
|
|
2974
2761
|
}
|
|
2975
2762
|
async setGroupAccess(groupId, access) {
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2763
|
+
await this.#requireClient().group.setSetting(
|
|
2764
|
+
groupId,
|
|
2765
|
+
"announcement",
|
|
2766
|
+
access === "closed"
|
|
2767
|
+
);
|
|
2979
2768
|
}
|
|
2980
2769
|
async getGroupInviteCode(groupId) {
|
|
2981
|
-
const code = await this.#
|
|
2770
|
+
const code = await this.#requireClient().group.queryInviteCode(groupId);
|
|
2982
2771
|
if (!code) {
|
|
2983
2772
|
throw new WhaNextError(
|
|
2984
2773
|
"PROVIDER_ERROR",
|
|
@@ -2988,139 +2777,300 @@ var BaileysProvider = class {
|
|
|
2988
2777
|
return code;
|
|
2989
2778
|
}
|
|
2990
2779
|
async revokeGroupInvite(groupId) {
|
|
2991
|
-
const
|
|
2992
|
-
if (!code) {
|
|
2780
|
+
const result = await this.#requireClient().group.revokeInvite(groupId);
|
|
2781
|
+
if (!result.code) {
|
|
2993
2782
|
throw new WhaNextError(
|
|
2994
2783
|
"PROVIDER_ERROR",
|
|
2995
2784
|
"WhatsApp did not return a new group invite code."
|
|
2996
2785
|
);
|
|
2997
2786
|
}
|
|
2998
|
-
return code;
|
|
2787
|
+
return result.code;
|
|
2999
2788
|
}
|
|
3000
2789
|
async setMessagePin(groupId, key, pinned) {
|
|
3001
|
-
await this.#
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
2790
|
+
await this.#requireClient().message.send(groupId, pinned ? {
|
|
2791
|
+
type: "pin",
|
|
2792
|
+
target: this.#toZapoKey(key),
|
|
2793
|
+
durationSecs: 604800
|
|
2794
|
+
} : {
|
|
2795
|
+
type: "unpin",
|
|
2796
|
+
target: this.#toZapoKey(key)
|
|
3005
2797
|
});
|
|
3006
2798
|
}
|
|
3007
2799
|
async updateParticipant(groupId, memberId, action) {
|
|
3008
|
-
const
|
|
3009
|
-
|
|
3010
|
-
const
|
|
2800
|
+
const group = this.#requireClient().group;
|
|
2801
|
+
const results = action === "remove" ? await group.removeParticipants(groupId, [memberId]) : action === "promote" ? await group.promoteParticipants(groupId, [memberId]) : await group.demoteParticipants(groupId, [memberId]);
|
|
2802
|
+
const result = results[0];
|
|
2803
|
+
const success = result?.status === "ok";
|
|
2804
|
+
const status = success ? "200" : String(result?.code ?? result?.status ?? "unknown");
|
|
3011
2805
|
return {
|
|
3012
|
-
success
|
|
2806
|
+
success,
|
|
3013
2807
|
status,
|
|
3014
2808
|
...result?.jid ? { memberId: result.jid } : {}
|
|
3015
2809
|
};
|
|
3016
2810
|
}
|
|
3017
2811
|
async setPresence(chatId, state) {
|
|
3018
|
-
const
|
|
3019
|
-
const presence =
|
|
3020
|
-
await
|
|
3021
|
-
}
|
|
3022
|
-
async rejectCall(callId, from) {
|
|
3023
|
-
await this.#requireSocket().rejectCall(callId, from);
|
|
2812
|
+
const value = state === "typing" ? "composing" : state === "recording" ? "recording" : "paused";
|
|
2813
|
+
const presence = this.#requireClient().presence;
|
|
2814
|
+
await presence.sendChatstate(chatId, { state: value });
|
|
3024
2815
|
}
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
2816
|
+
async rejectCall(callId, _from) {
|
|
2817
|
+
this.#requireClient();
|
|
2818
|
+
if (!this.#voip) {
|
|
2819
|
+
throw new WhaNextError(
|
|
2820
|
+
"PROVIDER_ERROR",
|
|
2821
|
+
"WhatsApp call support is unavailable because the Zapo VoIP plugin could not be loaded.",
|
|
2822
|
+
{ recoverable: true }
|
|
2823
|
+
);
|
|
2824
|
+
}
|
|
2825
|
+
await this.#voip.rejectCall(callId);
|
|
2826
|
+
}
|
|
2827
|
+
async #ensureClient() {
|
|
2828
|
+
if (this.#client) return this.#client;
|
|
2829
|
+
await mkdir(this.#options.auth, { recursive: true });
|
|
2830
|
+
const store = createStore({
|
|
2831
|
+
backends: {
|
|
2832
|
+
sqlite: createSqliteStore({
|
|
2833
|
+
path: join(this.#options.auth, "state.sqlite"),
|
|
2834
|
+
driver: "auto"
|
|
2835
|
+
})
|
|
2836
|
+
},
|
|
2837
|
+
providers: {
|
|
2838
|
+
auth: "sqlite",
|
|
2839
|
+
signal: "sqlite",
|
|
2840
|
+
preKey: "sqlite",
|
|
2841
|
+
session: "sqlite",
|
|
2842
|
+
identity: "sqlite",
|
|
2843
|
+
senderKey: "sqlite",
|
|
2844
|
+
appState: "sqlite",
|
|
2845
|
+
privacyToken: "sqlite",
|
|
2846
|
+
messages: "none",
|
|
2847
|
+
threads: "none",
|
|
2848
|
+
contacts: "none"
|
|
2849
|
+
},
|
|
2850
|
+
cacheProviders: {
|
|
2851
|
+
messageSecret: "sqlite"
|
|
3029
2852
|
}
|
|
3030
|
-
this.#saveQueue = this.#saveQueue.then(() => this.#saveCredentials?.()).then(() => void 0);
|
|
3031
2853
|
});
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
2854
|
+
const plugins = [];
|
|
2855
|
+
try {
|
|
2856
|
+
const { voipPlugin } = await import("@zapo-js/voip");
|
|
2857
|
+
plugins.push(voipPlugin({ logLevel: "warn" }));
|
|
2858
|
+
} catch (error) {
|
|
2859
|
+
this.#logger.warn("Zapo VoIP support is unavailable; call events and rejection are disabled.", {
|
|
2860
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2861
|
+
});
|
|
2862
|
+
}
|
|
2863
|
+
const client = new WaClient({
|
|
2864
|
+
store,
|
|
2865
|
+
sessionId: this.#options.sessionId ?? "default",
|
|
2866
|
+
markOnlineOnConnect: false,
|
|
2867
|
+
deviceBrowser: this.#deviceBrowser(),
|
|
2868
|
+
deviceOsDisplayName: this.#deviceOsDisplayName(),
|
|
2869
|
+
history: { enabled: false },
|
|
2870
|
+
addons: {
|
|
2871
|
+
autoDecrypt: true,
|
|
2872
|
+
persistAllSecrets: true
|
|
2873
|
+
},
|
|
2874
|
+
media: { processor: createMediaProcessor() },
|
|
2875
|
+
plugins
|
|
2876
|
+
}, new WhaNextZapoLogger(this.#logger));
|
|
2877
|
+
this.#client = client;
|
|
2878
|
+
this.#voip = client.voip;
|
|
2879
|
+
this.#bind(client);
|
|
2880
|
+
return client;
|
|
2881
|
+
}
|
|
2882
|
+
#bind(client) {
|
|
2883
|
+
client.on("auth_pairing_required", () => {
|
|
2884
|
+
this.#markPairingReady();
|
|
3042
2885
|
});
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
if (!key.id || !key.remoteJid) continue;
|
|
3046
|
-
const stored = this.#messageStore.get(this.#messageStoreKey(key));
|
|
3047
|
-
if (update.message === null) {
|
|
3048
|
-
const message = stored ? normalizeBaileysMessage(stored) : void 0;
|
|
3049
|
-
const deletionKey = update.key;
|
|
3050
|
-
const deletedByMe = deletionKey?.fromMe === true;
|
|
3051
|
-
const deletedById = deletionKey?.participant ?? deletionKey?.participantAlt ?? (deletedByMe ? this.#socket?.user?.id : deletionKey?.remoteJid ?? void 0);
|
|
3052
|
-
void this.#events.emit("messageDeleted", {
|
|
3053
|
-
key: message?.keys ?? normalizeKey(key),
|
|
3054
|
-
...message ? { message } : {},
|
|
3055
|
-
deletedByMe,
|
|
3056
|
-
...deletedById ? { deletedById } : {},
|
|
3057
|
-
deletedAt: /* @__PURE__ */ new Date()
|
|
3058
|
-
});
|
|
3059
|
-
continue;
|
|
3060
|
-
}
|
|
3061
|
-
if (!update.message?.editedMessage?.message) continue;
|
|
3062
|
-
const editedRaw = {
|
|
3063
|
-
...stored ?? {},
|
|
3064
|
-
key: {
|
|
3065
|
-
...stored?.key ?? {},
|
|
3066
|
-
...key
|
|
3067
|
-
},
|
|
3068
|
-
message: update.message,
|
|
3069
|
-
messageTimestamp: update.messageTimestamp ?? stored?.messageTimestamp ?? Math.floor(Date.now() / 1e3)
|
|
3070
|
-
};
|
|
3071
|
-
this.#emitMessageEdited(key, editedRaw, stored);
|
|
3072
|
-
}
|
|
2886
|
+
client.on("auth_qr", () => {
|
|
2887
|
+
this.#markPairingReady();
|
|
3073
2888
|
});
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
if (group.id) {
|
|
3077
|
-
this.#invalidateGroupMetadata(group.id);
|
|
3078
|
-
void this.#events.emit("groupChanged", { groupId: group.id });
|
|
3079
|
-
}
|
|
3080
|
-
}
|
|
2889
|
+
client.on("auth_paired", () => {
|
|
2890
|
+
this.#pairingRequired = false;
|
|
3081
2891
|
});
|
|
3082
|
-
|
|
3083
|
-
this.#
|
|
3084
|
-
const change = this.#groupParticipantsChanged(update);
|
|
3085
|
-
void this.#events.emit("groupParticipantsChanged", change);
|
|
3086
|
-
const { id } = update;
|
|
3087
|
-
void this.#events.emit("groupChanged", { groupId: id });
|
|
2892
|
+
client.on("message", (event) => {
|
|
2893
|
+
this.#handleMessage(event);
|
|
3088
2894
|
});
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
2895
|
+
client.on("message_send", (event) => {
|
|
2896
|
+
if (!event.id || !event.message) return;
|
|
2897
|
+
this.#remember({
|
|
2898
|
+
key: {
|
|
2899
|
+
id: event.id,
|
|
2900
|
+
remoteJid: event.to,
|
|
2901
|
+
fromMe: true
|
|
2902
|
+
},
|
|
2903
|
+
message: event.message,
|
|
2904
|
+
timestampSeconds: Math.floor(Date.now() / 1e3)
|
|
2905
|
+
});
|
|
2906
|
+
});
|
|
2907
|
+
client.on("message_protocol", (event) => {
|
|
2908
|
+
this.#handleProtocolEvent(event);
|
|
2909
|
+
});
|
|
2910
|
+
client.on("group", (event) => {
|
|
2911
|
+
this.#handleGroupEvent(event);
|
|
2912
|
+
});
|
|
2913
|
+
if (this.#voip) {
|
|
2914
|
+
const voipClient = client;
|
|
2915
|
+
voipClient.on("voip_call_incoming", (event) => {
|
|
2916
|
+
const call = this.#normalizeVoipCall(event, "offer");
|
|
2917
|
+
if (call) void this.#events.emit("call", call);
|
|
2918
|
+
});
|
|
2919
|
+
voipClient.on("voip_call_state", (event) => {
|
|
2920
|
+
if (event.stateData?.state === "ended") return;
|
|
2921
|
+
const call = this.#normalizeVoipCall(event);
|
|
2922
|
+
if (call && call.status !== "offer") void this.#events.emit("call", call);
|
|
2923
|
+
});
|
|
2924
|
+
voipClient.on("voip_call_ended", (event) => {
|
|
2925
|
+
const call = this.#normalizeVoipCall(
|
|
2926
|
+
event,
|
|
2927
|
+
this.#callEndStatus(event.stateData?.endReason)
|
|
2928
|
+
);
|
|
2929
|
+
if (call) void this.#events.emit("call", call);
|
|
2930
|
+
});
|
|
2931
|
+
}
|
|
2932
|
+
client.on("connection", (event) => {
|
|
2933
|
+
void this.#handleConnectionEvent(client, event);
|
|
3093
2934
|
});
|
|
3094
|
-
|
|
3095
|
-
|
|
2935
|
+
}
|
|
2936
|
+
#handleMessage(event) {
|
|
2937
|
+
const stored = event;
|
|
2938
|
+
if (this.#isOfflineMessage(stored)) {
|
|
2939
|
+
this.#logger.debug("Ignored message queued before the current connection.", {
|
|
2940
|
+
messageId: stored.key.id ?? void 0,
|
|
2941
|
+
chatId: stored.key.remoteJid ?? void 0,
|
|
2942
|
+
timestampSeconds: stored.timestampSeconds ?? void 0
|
|
2943
|
+
});
|
|
2944
|
+
return;
|
|
2945
|
+
}
|
|
2946
|
+
if (stored.key?.id && stored.message) this.#remember(stored);
|
|
2947
|
+
const quoted = extractQuotedZapoMessage(event);
|
|
2948
|
+
if (quoted) {
|
|
2949
|
+
const quotedStored = quoted;
|
|
2950
|
+
if (quotedStored.key?.id && quotedStored.message) this.#remember(quotedStored);
|
|
2951
|
+
}
|
|
2952
|
+
const message = normalizeZapoMessage(event);
|
|
2953
|
+
if (message) void this.#events.emit("message", message);
|
|
2954
|
+
}
|
|
2955
|
+
#handleProtocolEvent(event) {
|
|
2956
|
+
const protocol = event.protocolMessage ?? event.message?.protocolMessage;
|
|
2957
|
+
if (!protocol) return;
|
|
2958
|
+
const protocolKey = protocol.key;
|
|
2959
|
+
if (!protocolKey?.id) return;
|
|
2960
|
+
const remoteJid = protocolKey.remoteJid ?? event.key.remoteJid;
|
|
2961
|
+
const participant = protocolKey.participant ?? event.key.participant;
|
|
2962
|
+
const participantAlt = protocolKey.participantAlt ?? event.key.participantAlt;
|
|
2963
|
+
const target = {
|
|
2964
|
+
...protocolKey,
|
|
2965
|
+
...remoteJid !== void 0 ? { remoteJid } : {},
|
|
2966
|
+
...participant !== void 0 ? { participant } : {},
|
|
2967
|
+
...participantAlt !== void 0 ? { participantAlt } : {}
|
|
2968
|
+
};
|
|
2969
|
+
if (!target.remoteJid) return;
|
|
2970
|
+
const stored = this.#findStoredMessage(target);
|
|
2971
|
+
const type = protocol?.type;
|
|
2972
|
+
if (type === proto.Message.ProtocolMessage.Type.REVOKE) {
|
|
2973
|
+
const previous2 = stored ? normalizeZapoMessage(stored) : void 0;
|
|
2974
|
+
const deletedByMe = event.key.fromMe === true;
|
|
2975
|
+
const deletedById = event.key.participant ?? event.key.participantAlt ?? (deletedByMe ? this.getCurrentUserIds()[0] : event.key.remoteJid ?? void 0);
|
|
2976
|
+
void this.#events.emit("messageDeleted", {
|
|
2977
|
+
key: previous2?.keys ?? normalizeZapoKey(target),
|
|
2978
|
+
...previous2 ? { message: previous2 } : {},
|
|
2979
|
+
deletedByMe,
|
|
2980
|
+
...deletedById ? { deletedById } : {},
|
|
2981
|
+
deletedAt: /* @__PURE__ */ new Date()
|
|
2982
|
+
});
|
|
2983
|
+
return;
|
|
2984
|
+
}
|
|
2985
|
+
if (type !== proto.Message.ProtocolMessage.Type.MESSAGE_EDIT || !protocol.editedMessage) {
|
|
2986
|
+
return;
|
|
2987
|
+
}
|
|
2988
|
+
const pushName = event.pushName ?? stored?.pushName;
|
|
2989
|
+
const edited = {
|
|
2990
|
+
...stored ?? {},
|
|
2991
|
+
key: {
|
|
2992
|
+
...stored?.key ?? {},
|
|
2993
|
+
...target
|
|
2994
|
+
},
|
|
2995
|
+
message: protocol.editedMessage,
|
|
2996
|
+
timestampSeconds: toSeconds(protocol.timestampMs) ?? event.timestampSeconds ?? stored?.timestampSeconds ?? Math.floor(Date.now() / 1e3),
|
|
2997
|
+
...pushName !== void 0 ? { pushName } : {}
|
|
2998
|
+
};
|
|
2999
|
+
const message = normalizeZapoMessage(edited);
|
|
3000
|
+
if (!message) return;
|
|
3001
|
+
const previous = stored ? normalizeZapoMessage(stored) : void 0;
|
|
3002
|
+
this.#remember(edited);
|
|
3003
|
+
const editedByMe = event.key.fromMe === true;
|
|
3004
|
+
const editedById = event.key.participant ?? event.key.participantAlt ?? (editedByMe ? this.getCurrentUserIds()[0] : event.key.remoteJid ?? void 0);
|
|
3005
|
+
void this.#events.emit("messageEdited", {
|
|
3006
|
+
key: message.keys,
|
|
3007
|
+
...previous ? { previous } : {},
|
|
3008
|
+
message,
|
|
3009
|
+
editedByMe,
|
|
3010
|
+
...editedById ? { editedById } : {},
|
|
3011
|
+
editedAt: message.timestamp
|
|
3096
3012
|
});
|
|
3097
3013
|
}
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
if (
|
|
3014
|
+
#handleGroupEvent(event) {
|
|
3015
|
+
const groupId = event.groupJid;
|
|
3016
|
+
if (!groupId) return;
|
|
3017
|
+
const action = this.#groupAction(event.action);
|
|
3018
|
+
const participantIds = this.#groupParticipantIds(event);
|
|
3019
|
+
if (action && participantIds.length > 0) {
|
|
3020
|
+
const authorId = event.authorJid;
|
|
3021
|
+
const change = {
|
|
3022
|
+
groupId,
|
|
3023
|
+
action,
|
|
3024
|
+
participantIds,
|
|
3025
|
+
...authorId ? { authorId } : {}
|
|
3026
|
+
};
|
|
3027
|
+
void this.#events.emit("groupParticipantsChanged", change);
|
|
3028
|
+
}
|
|
3029
|
+
void this.#events.emit("groupChanged", { groupId });
|
|
3030
|
+
}
|
|
3031
|
+
async #handleConnectionEvent(client, event) {
|
|
3032
|
+
if (client !== this.#client) return;
|
|
3033
|
+
if (event.status === "open") {
|
|
3034
|
+
this.#connectPromise = void 0;
|
|
3035
|
+
this.#connected = true;
|
|
3036
|
+
this.#connectedAtSeconds = Math.floor(Date.now() / 1e3);
|
|
3101
3037
|
this.#reconnectAttempt = 0;
|
|
3102
3038
|
await this.#events.emit("connection", { state: "connected" });
|
|
3103
3039
|
return;
|
|
3104
3040
|
}
|
|
3105
|
-
|
|
3041
|
+
this.#connectPromise = void 0;
|
|
3042
|
+
this.#connected = false;
|
|
3043
|
+
const error = event.reason instanceof Error ? event.reason : event.reason ? new Error(String(event.reason)) : void 0;
|
|
3044
|
+
if (this.#intentionalClose || event.isLogout) {
|
|
3106
3045
|
await this.#events.emit("connection", {
|
|
3107
|
-
state: "
|
|
3108
|
-
|
|
3046
|
+
state: "closed",
|
|
3047
|
+
...error ? { error } : {}
|
|
3109
3048
|
});
|
|
3110
3049
|
return;
|
|
3111
3050
|
}
|
|
3112
|
-
this.#socket = void 0;
|
|
3113
|
-
if (this.#intentionalClose || this.#isTerminal(error)) {
|
|
3114
|
-
await this.#events.emit("connection", { state: "closed", ...error ? { error } : {} });
|
|
3115
|
-
return;
|
|
3116
|
-
}
|
|
3117
3051
|
await this.#scheduleReconnect(error);
|
|
3118
3052
|
}
|
|
3053
|
+
#startConnect(client) {
|
|
3054
|
+
const promise = client.connect();
|
|
3055
|
+
this.#connectPromise = promise;
|
|
3056
|
+
void promise.catch(async (error) => {
|
|
3057
|
+
if (this.#connectPromise !== promise) return;
|
|
3058
|
+
this.#connectPromise = void 0;
|
|
3059
|
+
if (this.#intentionalClose) return;
|
|
3060
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
3061
|
+
this.#logger.warn("WhatsApp connection attempt failed.", { error: normalized });
|
|
3062
|
+
await this.#scheduleReconnect(normalized);
|
|
3063
|
+
});
|
|
3064
|
+
}
|
|
3119
3065
|
async #scheduleReconnect(error) {
|
|
3066
|
+
if (this.#reconnectTimer) return;
|
|
3120
3067
|
const options = this.#options.reconnect;
|
|
3121
3068
|
const maxAttempts = options?.maxAttempts ?? 10;
|
|
3122
3069
|
if (options?.enabled === false || this.#reconnectAttempt >= maxAttempts) {
|
|
3123
|
-
await this.#events.emit("connection", {
|
|
3070
|
+
await this.#events.emit("connection", {
|
|
3071
|
+
state: "closed",
|
|
3072
|
+
...error ? { error } : {}
|
|
3073
|
+
});
|
|
3124
3074
|
return;
|
|
3125
3075
|
}
|
|
3126
3076
|
this.#reconnectAttempt += 1;
|
|
@@ -3132,184 +3082,120 @@ var BaileysProvider = class {
|
|
|
3132
3082
|
const initial = options?.initialDelayMs ?? 1e3;
|
|
3133
3083
|
const maximum = options?.maxDelayMs ?? 3e4;
|
|
3134
3084
|
const delay = Math.min(maximum, initial * 2 ** (this.#reconnectAttempt - 1));
|
|
3135
|
-
this.#reconnectTimer = setTimeout(
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
);
|
|
3139
|
-
}
|
|
3140
|
-
#browserDescription() {
|
|
3141
|
-
if (this.#options.browser === "macos" /* MacOS */) return Browsers.macOS("Safari");
|
|
3142
|
-
if (this.#options.browser === "ubuntu" /* Ubuntu */) return Browsers.ubuntu("Chrome");
|
|
3143
|
-
return Browsers.windows("Brave");
|
|
3144
|
-
}
|
|
3145
|
-
#isTerminal(error) {
|
|
3146
|
-
const statusCode = this.#statusCode(error);
|
|
3147
|
-
return statusCode === DisconnectReason.loggedOut || statusCode === DisconnectReason.badSession || statusCode === DisconnectReason.connectionReplaced;
|
|
3148
|
-
}
|
|
3149
|
-
#statusCode(error) {
|
|
3150
|
-
return error?.output?.statusCode;
|
|
3151
|
-
}
|
|
3152
|
-
#requireSocket() {
|
|
3153
|
-
if (!this.#socket) {
|
|
3154
|
-
throw new WhaNextError(
|
|
3155
|
-
"CONNECTION_CLOSED",
|
|
3156
|
-
"WhatsApp is not connected.",
|
|
3157
|
-
{ recoverable: true }
|
|
3158
|
-
);
|
|
3159
|
-
}
|
|
3160
|
-
return this.#socket;
|
|
3085
|
+
this.#reconnectTimer = setTimeout(() => {
|
|
3086
|
+
this.#reconnectTimer = void 0;
|
|
3087
|
+
void this.connect();
|
|
3088
|
+
}, delay + Math.floor(Math.random() * 250));
|
|
3161
3089
|
}
|
|
3162
3090
|
async #sendButtons(chatId, content, replyTo) {
|
|
3163
|
-
const
|
|
3164
|
-
const
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
}
|
|
3171
|
-
const interactiveMessage = proto2.Message.InteractiveMessage.create({
|
|
3172
|
-
...content.title !== void 0 ? {
|
|
3173
|
-
header: {
|
|
3174
|
-
title: content.title,
|
|
3175
|
-
hasMediaAttachment: false
|
|
3176
|
-
}
|
|
3177
|
-
} : {},
|
|
3178
|
-
body: { text: content.text },
|
|
3179
|
-
...content.footer !== void 0 ? { footer: { text: content.footer } } : {},
|
|
3180
|
-
...content.mentions && content.mentions.length > 0 ? {
|
|
3181
|
-
contextInfo: {
|
|
3182
|
-
mentionedJid: this.#mentions(content.mentions)
|
|
3183
|
-
}
|
|
3184
|
-
} : {},
|
|
3185
|
-
nativeFlowMessage: {
|
|
3186
|
-
buttons: content.buttons.map((button) => {
|
|
3187
|
-
if (button.type === "copy") {
|
|
3188
|
-
return {
|
|
3189
|
-
name: "cta_copy",
|
|
3190
|
-
buttonParamsJson: JSON.stringify({
|
|
3191
|
-
display_text: button.label,
|
|
3192
|
-
copy_code: button.code
|
|
3193
|
-
})
|
|
3194
|
-
};
|
|
3091
|
+
const mentions = content.mentions ? this.#mentions(content.mentions) : [];
|
|
3092
|
+
const raw = {
|
|
3093
|
+
interactiveMessage: {
|
|
3094
|
+
...content.title !== void 0 ? {
|
|
3095
|
+
header: {
|
|
3096
|
+
title: content.title,
|
|
3097
|
+
hasMediaAttachment: false
|
|
3195
3098
|
}
|
|
3196
|
-
|
|
3099
|
+
} : {},
|
|
3100
|
+
body: { text: content.text },
|
|
3101
|
+
...content.footer !== void 0 ? { footer: { text: content.footer } } : {},
|
|
3102
|
+
...mentions.length > 0 ? { contextInfo: { mentionedJid: mentions } } : {},
|
|
3103
|
+
nativeFlowMessage: {
|
|
3104
|
+
buttons: content.buttons.map((button) => button.type === "copy" ? {
|
|
3105
|
+
name: "cta_copy",
|
|
3106
|
+
buttonParamsJson: JSON.stringify({
|
|
3107
|
+
display_text: button.label,
|
|
3108
|
+
copy_code: button.code
|
|
3109
|
+
})
|
|
3110
|
+
} : {
|
|
3197
3111
|
name: "cta_url",
|
|
3198
3112
|
buttonParamsJson: JSON.stringify({
|
|
3199
3113
|
display_text: button.label,
|
|
3200
3114
|
url: button.url,
|
|
3201
3115
|
merchant_url: button.url
|
|
3202
3116
|
})
|
|
3203
|
-
}
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
messageVersion: 1
|
|
3207
|
-
}
|
|
3208
|
-
});
|
|
3209
|
-
const quoted = replyTo ? {
|
|
3210
|
-
key: this.#toWaKey(replyTo),
|
|
3211
|
-
message: { conversation: "" }
|
|
3212
|
-
} : void 0;
|
|
3213
|
-
const generated = generateWAMessageFromContent(
|
|
3214
|
-
chatId,
|
|
3215
|
-
{ interactiveMessage },
|
|
3216
|
-
{
|
|
3217
|
-
userJid,
|
|
3218
|
-
...quoted ? { quoted } : {}
|
|
3219
|
-
}
|
|
3220
|
-
);
|
|
3221
|
-
const messageId = generated.key.id;
|
|
3222
|
-
if (!generated.message || !messageId) {
|
|
3223
|
-
throw new WhaNextError(
|
|
3224
|
-
"PROVIDER_ERROR",
|
|
3225
|
-
"WhatsApp could not generate the interactive message."
|
|
3226
|
-
);
|
|
3227
|
-
}
|
|
3228
|
-
await socket.relayMessage(chatId, generated.message, {
|
|
3229
|
-
messageId,
|
|
3230
|
-
additionalNodes: this.#interactiveRelayNodes(chatId)
|
|
3231
|
-
});
|
|
3232
|
-
return this.#sent(generated);
|
|
3233
|
-
}
|
|
3234
|
-
#interactiveRelayNodes(chatId) {
|
|
3235
|
-
const bizNode = {
|
|
3236
|
-
tag: "biz",
|
|
3237
|
-
attrs: {
|
|
3238
|
-
actual_actors: "2",
|
|
3239
|
-
host_storage: "2",
|
|
3240
|
-
privacy_mode_ts: (Math.floor(Date.now() / 1e3) - 77980457).toString()
|
|
3241
|
-
},
|
|
3242
|
-
content: [
|
|
3243
|
-
{
|
|
3244
|
-
tag: "interactive",
|
|
3245
|
-
attrs: { type: "native_flow", v: "1" },
|
|
3246
|
-
content: [
|
|
3247
|
-
{
|
|
3248
|
-
tag: "native_flow",
|
|
3249
|
-
attrs: { v: "9", name: "mixed" }
|
|
3250
|
-
}
|
|
3251
|
-
]
|
|
3252
|
-
},
|
|
3253
|
-
{
|
|
3254
|
-
tag: "quality_control",
|
|
3255
|
-
attrs: { source_type: "third_party" }
|
|
3117
|
+
}),
|
|
3118
|
+
messageParamsJson: "{}",
|
|
3119
|
+
messageVersion: 1
|
|
3256
3120
|
}
|
|
3257
|
-
|
|
3121
|
+
}
|
|
3258
3122
|
};
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
bizNode
|
|
3265
|
-
];
|
|
3123
|
+
const result = await this.#requireClient().message.send(chatId, raw, {
|
|
3124
|
+
...replyTo ? { quote: this.#toZapoKey(replyTo) } : {},
|
|
3125
|
+
...mentions.length > 0 ? { mentions } : {}
|
|
3126
|
+
});
|
|
3127
|
+
return this.#sent(result, chatId);
|
|
3266
3128
|
}
|
|
3267
|
-
#toContent(content) {
|
|
3129
|
+
async #toContent(content) {
|
|
3268
3130
|
if ("text" in content) {
|
|
3269
3131
|
return {
|
|
3270
|
-
text: content.text,
|
|
3271
|
-
|
|
3132
|
+
value: { type: "text", text: content.text },
|
|
3133
|
+
mentions: content.mentions ? this.#mentions(content.mentions) : []
|
|
3272
3134
|
};
|
|
3273
3135
|
}
|
|
3274
3136
|
if ("image" in content) {
|
|
3275
3137
|
return {
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3138
|
+
value: {
|
|
3139
|
+
type: "image",
|
|
3140
|
+
media: await this.#media(content.image),
|
|
3141
|
+
...content.caption !== void 0 ? { caption: content.caption } : {}
|
|
3142
|
+
},
|
|
3143
|
+
mentions: content.mentions ? this.#mentions(content.mentions) : [],
|
|
3279
3144
|
...content.viewOnce !== void 0 ? { viewOnce: content.viewOnce } : {}
|
|
3280
3145
|
};
|
|
3281
3146
|
}
|
|
3282
3147
|
if ("video" in content) {
|
|
3283
3148
|
return {
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3149
|
+
value: {
|
|
3150
|
+
type: "video",
|
|
3151
|
+
media: await this.#media(content.video),
|
|
3152
|
+
...content.caption !== void 0 ? { caption: content.caption } : {},
|
|
3153
|
+
...content.gif !== void 0 ? { gifPlayback: content.gif } : {}
|
|
3154
|
+
},
|
|
3155
|
+
mentions: content.mentions ? this.#mentions(content.mentions) : [],
|
|
3156
|
+
...content.viewOnce !== void 0 ? { viewOnce: content.viewOnce } : {}
|
|
3289
3157
|
};
|
|
3290
3158
|
}
|
|
3291
3159
|
if ("sticker" in content) {
|
|
3292
|
-
return {
|
|
3160
|
+
return {
|
|
3161
|
+
value: {
|
|
3162
|
+
type: "sticker",
|
|
3163
|
+
media: await this.#media(content.sticker),
|
|
3164
|
+
mimetype: "image/webp"
|
|
3165
|
+
},
|
|
3166
|
+
mentions: []
|
|
3167
|
+
};
|
|
3293
3168
|
}
|
|
3294
3169
|
return {
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3170
|
+
value: {
|
|
3171
|
+
type: "audio",
|
|
3172
|
+
media: await this.#media(content.audio),
|
|
3173
|
+
...content.mimetype ? { mimetype: content.mimetype } : {},
|
|
3174
|
+
...content.voice !== void 0 ? { ptt: content.voice } : {}
|
|
3175
|
+
},
|
|
3176
|
+
mentions: []
|
|
3298
3177
|
};
|
|
3299
3178
|
}
|
|
3300
|
-
#media(source) {
|
|
3301
|
-
if (source instanceof Uint8Array)
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
if (
|
|
3305
|
-
|
|
3179
|
+
async #media(source) {
|
|
3180
|
+
if (source instanceof Uint8Array) return source;
|
|
3181
|
+
if ("path" in source) return source.path;
|
|
3182
|
+
const response = await fetch(source.url);
|
|
3183
|
+
if (!response.ok) {
|
|
3184
|
+
throw new WhaNextError(
|
|
3185
|
+
"PROVIDER_ERROR",
|
|
3186
|
+
"Could not download the remote media source.",
|
|
3187
|
+
{
|
|
3188
|
+
context: { status: response.status },
|
|
3189
|
+
recoverable: response.status >= 500
|
|
3190
|
+
}
|
|
3191
|
+
);
|
|
3306
3192
|
}
|
|
3307
|
-
return
|
|
3193
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
3308
3194
|
}
|
|
3309
3195
|
#mentions(mentions) {
|
|
3310
3196
|
return mentions.map((mention) => typeof mention === "string" ? mention : mention.mentionId);
|
|
3311
3197
|
}
|
|
3312
|
-
#
|
|
3198
|
+
#toZapoKey(key) {
|
|
3313
3199
|
return {
|
|
3314
3200
|
id: key.id,
|
|
3315
3201
|
remoteJid: key.chatId,
|
|
@@ -3317,101 +3203,78 @@ var BaileysProvider = class {
|
|
|
3317
3203
|
...key.participantId ? { participant: key.participantId } : {}
|
|
3318
3204
|
};
|
|
3319
3205
|
}
|
|
3320
|
-
#sent(
|
|
3321
|
-
if (!
|
|
3322
|
-
throw new WhaNextError(
|
|
3206
|
+
#sent(result, chatId) {
|
|
3207
|
+
if (!result.id) {
|
|
3208
|
+
throw new WhaNextError(
|
|
3209
|
+
"PROVIDER_ERROR",
|
|
3210
|
+
"WhatsApp did not confirm the sent message."
|
|
3211
|
+
);
|
|
3323
3212
|
}
|
|
3324
|
-
if (message.message) this.#remember(message);
|
|
3325
3213
|
return {
|
|
3326
|
-
id:
|
|
3327
|
-
chatId
|
|
3328
|
-
keys:
|
|
3214
|
+
id: result.id,
|
|
3215
|
+
chatId,
|
|
3216
|
+
keys: {
|
|
3217
|
+
id: result.id,
|
|
3218
|
+
chatId,
|
|
3219
|
+
fromMe: true
|
|
3220
|
+
},
|
|
3329
3221
|
timestamp: /* @__PURE__ */ new Date()
|
|
3330
3222
|
};
|
|
3331
3223
|
}
|
|
3332
|
-
#
|
|
3224
|
+
#normalizeVoipCall(event, forcedStatus) {
|
|
3225
|
+
const id = event.callId;
|
|
3226
|
+
const from = event.callerPn ?? event.peerJid ?? event.callCreator;
|
|
3227
|
+
const chatId = event.groupJid ?? event.peerJid ?? from;
|
|
3228
|
+
if (!id || !from || !chatId) return void 0;
|
|
3333
3229
|
return {
|
|
3334
|
-
id
|
|
3335
|
-
chatId
|
|
3336
|
-
from
|
|
3337
|
-
status: this.#callStatus(
|
|
3338
|
-
isVideo:
|
|
3339
|
-
isGroup: Boolean(
|
|
3340
|
-
date:
|
|
3341
|
-
};
|
|
3342
|
-
}
|
|
3343
|
-
#groupParticipantsChanged(change) {
|
|
3344
|
-
const participantIds = change.participants.map((participant) => participant.id).filter((id) => Boolean(id));
|
|
3345
|
-
return {
|
|
3346
|
-
groupId: change.id,
|
|
3347
|
-
action: change.action,
|
|
3348
|
-
participantIds,
|
|
3349
|
-
...change.author ? { authorId: change.author } : {}
|
|
3230
|
+
id,
|
|
3231
|
+
chatId,
|
|
3232
|
+
from,
|
|
3233
|
+
status: forcedStatus ?? this.#callStatus(event.stateData?.state),
|
|
3234
|
+
isVideo: event.mediaType === "video",
|
|
3235
|
+
isGroup: Boolean(event.groupJid),
|
|
3236
|
+
date: event.createdAt ?? /* @__PURE__ */ new Date()
|
|
3350
3237
|
};
|
|
3351
3238
|
}
|
|
3352
3239
|
#callStatus(status) {
|
|
3353
|
-
|
|
3354
|
-
"offer"
|
|
3355
|
-
"
|
|
3356
|
-
|
|
3357
|
-
"
|
|
3358
|
-
"
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
},
|
|
3389
|
-
messageTimestamp: decrypted.timestamp ?? raw.messageTimestamp ?? stored.messageTimestamp ?? Math.floor(Date.now() / 1e3)
|
|
3390
|
-
};
|
|
3391
|
-
this.#emitMessageEdited(key, editedRaw, stored);
|
|
3392
|
-
} catch (error) {
|
|
3393
|
-
this.#logger.warn("Could not decrypt the encrypted message edit.", {
|
|
3394
|
-
messageId: targetKey.id,
|
|
3395
|
-
error: error instanceof Error ? error.message : String(error)
|
|
3396
|
-
});
|
|
3397
|
-
}
|
|
3398
|
-
return true;
|
|
3240
|
+
switch (status?.toLowerCase()) {
|
|
3241
|
+
case "offer":
|
|
3242
|
+
case "initiating":
|
|
3243
|
+
return "offer";
|
|
3244
|
+
case "ringing":
|
|
3245
|
+
case "incoming_ringing":
|
|
3246
|
+
return "ringing";
|
|
3247
|
+
case "preaccept":
|
|
3248
|
+
case "connecting":
|
|
3249
|
+
return "preaccept";
|
|
3250
|
+
case "accept":
|
|
3251
|
+
case "accepted":
|
|
3252
|
+
case "active":
|
|
3253
|
+
return "accept";
|
|
3254
|
+
case "reject":
|
|
3255
|
+
case "rejected":
|
|
3256
|
+
case "terminate":
|
|
3257
|
+
case "terminated":
|
|
3258
|
+
case "ended":
|
|
3259
|
+
return "reject";
|
|
3260
|
+
default:
|
|
3261
|
+
return "timeout";
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
#callEndStatus(reason) {
|
|
3265
|
+
return reason?.toLowerCase() === "timeout" ? "timeout" : "reject";
|
|
3266
|
+
}
|
|
3267
|
+
#groupAction(action) {
|
|
3268
|
+
const value = action?.toLowerCase() ?? "";
|
|
3269
|
+
if (value.includes("promote")) return "promote";
|
|
3270
|
+
if (value.includes("demote")) return "demote";
|
|
3271
|
+
if (value.includes("remove") || value.includes("leave")) return "remove";
|
|
3272
|
+
if (value.includes("add") || value.includes("join")) return "add";
|
|
3273
|
+
if (value.includes("participant") || value.includes("modify")) return "modify";
|
|
3274
|
+
return void 0;
|
|
3399
3275
|
}
|
|
3400
|
-
#
|
|
3401
|
-
|
|
3402
|
-
const message = normalizeBaileysMessage(editedRaw);
|
|
3403
|
-
if (!message) return;
|
|
3404
|
-
this.#remember(editedRaw);
|
|
3405
|
-
const editedByMe = key.fromMe === true;
|
|
3406
|
-
const editedById = key.participant ?? key.participantAlt ?? (editedByMe ? this.#socket?.user?.id : key.remoteJid ?? void 0);
|
|
3407
|
-
void this.#events.emit("messageEdited", {
|
|
3408
|
-
key: message.keys,
|
|
3409
|
-
...previous ? { previous } : {},
|
|
3410
|
-
message,
|
|
3411
|
-
editedByMe,
|
|
3412
|
-
...editedById ? { editedById } : {},
|
|
3413
|
-
editedAt: message.timestamp
|
|
3414
|
-
});
|
|
3276
|
+
#groupParticipantIds(event) {
|
|
3277
|
+
return uniqueIdentities((event.participants ?? []).map((participant) => participant.jid ?? participant.lidJid ?? participant.phoneJid));
|
|
3415
3278
|
}
|
|
3416
3279
|
#findStoredMessage(key) {
|
|
3417
3280
|
const direct = this.#messageStore.get(this.#messageStoreKey(key));
|
|
@@ -3431,70 +3294,117 @@ var BaileysProvider = class {
|
|
|
3431
3294
|
if (oldest) this.#messageStore.delete(oldest);
|
|
3432
3295
|
}
|
|
3433
3296
|
}
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3297
|
+
#messageStoreKey(key) {
|
|
3298
|
+
return `${key.remoteJid ?? ""}:${key.id ?? ""}:${key.participant ?? key.participantAlt ?? ""}`;
|
|
3299
|
+
}
|
|
3300
|
+
#isOfflineMessage(message) {
|
|
3301
|
+
if (this.#options.processOfflineMessages === true) return false;
|
|
3302
|
+
if (message.offline === true) return true;
|
|
3303
|
+
if (!this.#connectedAtSeconds || message.timestampSeconds == null) return false;
|
|
3304
|
+
const timestamp = toSeconds(message.timestampSeconds);
|
|
3305
|
+
if (timestamp === void 0) return false;
|
|
3306
|
+
return timestamp < this.#connectedAtSeconds - 3;
|
|
3307
|
+
}
|
|
3308
|
+
#markPairingReady() {
|
|
3309
|
+
this.#pairingRequired = true;
|
|
3310
|
+
this.#resolvePairingReady?.();
|
|
3311
|
+
this.#resolvePairingReady = void 0;
|
|
3312
|
+
}
|
|
3313
|
+
#preparePairingGate() {
|
|
3314
|
+
this.#pairingRequired = false;
|
|
3315
|
+
this.#pairingReady = new Promise((resolve3) => {
|
|
3316
|
+
this.#resolvePairingReady = resolve3;
|
|
3317
|
+
});
|
|
3318
|
+
}
|
|
3319
|
+
#deviceBrowser() {
|
|
3320
|
+
return this.#options.browser === "macos" /* MacOS */ ? "safari" : "chrome";
|
|
3321
|
+
}
|
|
3322
|
+
#deviceOsDisplayName() {
|
|
3323
|
+
if (this.#options.browser === "macos" /* MacOS */) return "macOS";
|
|
3324
|
+
if (this.#options.browser === "ubuntu" /* Ubuntu */) return "Ubuntu";
|
|
3325
|
+
return "Windows";
|
|
3326
|
+
}
|
|
3327
|
+
#requireClient() {
|
|
3328
|
+
const client = this.#client;
|
|
3329
|
+
if (!client || !this.#connected) {
|
|
3330
|
+
throw new WhaNextError(
|
|
3331
|
+
"CONNECTION_CLOSED",
|
|
3332
|
+
"WhatsApp is not connected.",
|
|
3333
|
+
{ recoverable: true }
|
|
3334
|
+
);
|
|
3335
|
+
}
|
|
3336
|
+
return client;
|
|
3337
|
+
}
|
|
3338
|
+
async #withTimeout(promise, timeoutMs, message) {
|
|
3339
|
+
let timer;
|
|
3450
3340
|
try {
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3341
|
+
return await Promise.race([
|
|
3342
|
+
promise,
|
|
3343
|
+
new Promise((_, reject) => {
|
|
3344
|
+
timer = setTimeout(() => {
|
|
3345
|
+
reject(new WhaNextError(
|
|
3346
|
+
"CONNECTION_FAILED",
|
|
3347
|
+
message,
|
|
3348
|
+
{ recoverable: true }
|
|
3349
|
+
));
|
|
3350
|
+
}, timeoutMs);
|
|
3351
|
+
})
|
|
3352
|
+
]);
|
|
3456
3353
|
} finally {
|
|
3457
|
-
if (
|
|
3458
|
-
this.#groupMetadataRequests.delete(groupId);
|
|
3459
|
-
}
|
|
3354
|
+
if (timer) clearTimeout(timer);
|
|
3460
3355
|
}
|
|
3461
3356
|
}
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
if (oldest === void 0) return;
|
|
3472
|
-
this.#groupMetadataCache.delete(oldest);
|
|
3473
|
-
}
|
|
3357
|
+
};
|
|
3358
|
+
var WhaNextZapoLogger = class _WhaNextZapoLogger {
|
|
3359
|
+
level;
|
|
3360
|
+
#logger;
|
|
3361
|
+
#context;
|
|
3362
|
+
constructor(logger, context = {}) {
|
|
3363
|
+
this.#logger = logger;
|
|
3364
|
+
this.#context = context;
|
|
3365
|
+
this.level = logger.level === "debug" ? "debug" : logger.level === "warn" ? "warn" : logger.level === "error" || logger.level === "silent" ? "error" : "info";
|
|
3474
3366
|
}
|
|
3475
|
-
|
|
3476
|
-
this.#
|
|
3477
|
-
const generation = this.#groupMetadataGenerations.get(groupId) ?? 0;
|
|
3478
|
-
this.#groupMetadataGenerations.set(groupId, generation + 1);
|
|
3367
|
+
trace(message, context) {
|
|
3368
|
+
this.#logger.debug(message, this.#merge(context));
|
|
3479
3369
|
}
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3370
|
+
debug(message, context) {
|
|
3371
|
+
this.#logger.debug(message, this.#merge(context));
|
|
3372
|
+
}
|
|
3373
|
+
info(message, context) {
|
|
3374
|
+
this.#logger.info(message, this.#merge(context));
|
|
3375
|
+
}
|
|
3376
|
+
warn(message, context) {
|
|
3377
|
+
this.#logger.warn(message, this.#merge(context));
|
|
3378
|
+
}
|
|
3379
|
+
error(message, context) {
|
|
3380
|
+
this.#logger.error(message, this.#merge(context));
|
|
3381
|
+
}
|
|
3382
|
+
child(bindings) {
|
|
3383
|
+
return new _WhaNextZapoLogger(this.#logger, {
|
|
3384
|
+
...this.#context,
|
|
3385
|
+
...bindings
|
|
3386
|
+
});
|
|
3387
|
+
}
|
|
3388
|
+
#merge(context) {
|
|
3389
|
+
return context ? { ...this.#context, ...context } : this.#context;
|
|
3483
3390
|
}
|
|
3484
3391
|
};
|
|
3392
|
+
function toSeconds(value) {
|
|
3393
|
+
const raw = typeof value === "number" ? value : value?.toNumber ? value.toNumber() : value?.low;
|
|
3394
|
+
if (raw === void 0) return void 0;
|
|
3395
|
+
return raw > 1e10 ? Math.floor(raw / 1e3) : raw;
|
|
3396
|
+
}
|
|
3485
3397
|
|
|
3486
3398
|
// src/app/create.ts
|
|
3487
3399
|
async function create(options = {}) {
|
|
3488
3400
|
const logger = new Logger(options.logger);
|
|
3489
|
-
const provider = options.provider ?? new
|
|
3401
|
+
const provider = options.provider ?? new ZapoProvider({
|
|
3490
3402
|
auth: options.auth ?? "./session",
|
|
3491
3403
|
browser: options.browser ?? "windows" /* Windows */,
|
|
3492
3404
|
logger: logger.child("provider"),
|
|
3405
|
+
...options.accountId ? { sessionId: options.accountId } : {},
|
|
3493
3406
|
...options.messageCacheSize !== void 0 ? { messageCacheSize: options.messageCacheSize } : {},
|
|
3494
|
-
|
|
3495
|
-
...options.cache?.groupTtlMs !== void 0 ? { ttlMs: options.cache.groupTtlMs } : {},
|
|
3496
|
-
...options.cache?.memoryMaxEntries !== void 0 ? { maxEntries: options.cache.memoryMaxEntries } : {}
|
|
3497
|
-
},
|
|
3407
|
+
...options.processOfflineMessages !== void 0 ? { processOfflineMessages: options.processOfflineMessages } : {},
|
|
3498
3408
|
...options.reconnect ? { reconnect: options.reconnect } : {}
|
|
3499
3409
|
});
|
|
3500
3410
|
return new WhaNextApp(provider, {
|
|
@@ -3510,7 +3420,7 @@ async function create(options = {}) {
|
|
|
3510
3420
|
|
|
3511
3421
|
// src/app/multi-app.ts
|
|
3512
3422
|
import {
|
|
3513
|
-
join,
|
|
3423
|
+
join as join2,
|
|
3514
3424
|
resolve as resolve2
|
|
3515
3425
|
} from "path";
|
|
3516
3426
|
var MultiCommandRouter = class {
|
|
@@ -3656,7 +3566,7 @@ async function createMulti(options) {
|
|
|
3656
3566
|
}
|
|
3657
3567
|
normalizedIds.add(normalizedId);
|
|
3658
3568
|
if (account.provider === void 0) {
|
|
3659
|
-
const authPath = resolve2(account.auth ??
|
|
3569
|
+
const authPath = resolve2(account.auth ?? join2(authRoot, account.id));
|
|
3660
3570
|
if (authPaths.has(authPath)) {
|
|
3661
3571
|
throw new WhaNextError(
|
|
3662
3572
|
"ARGUMENT_INVALID",
|
|
@@ -3677,13 +3587,13 @@ async function createMulti(options) {
|
|
|
3677
3587
|
if (merged.mute?.enabled === true && merged.mute.store === void 0 && merged.mute.database === void 0) {
|
|
3678
3588
|
merged.mute = {
|
|
3679
3589
|
...merged.mute,
|
|
3680
|
-
database:
|
|
3590
|
+
database: join2("./data", `whanext-${id}.sqlite`)
|
|
3681
3591
|
};
|
|
3682
3592
|
}
|
|
3683
3593
|
const app = await create({
|
|
3684
3594
|
...merged,
|
|
3685
3595
|
accountId: id,
|
|
3686
|
-
auth: overrides.auth ??
|
|
3596
|
+
auth: overrides.auth ?? join2(authRoot, id)
|
|
3687
3597
|
});
|
|
3688
3598
|
apps.set(id, app);
|
|
3689
3599
|
}
|