keithbaileys 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/Defaults/index.js +8 -2
- package/lib/Socket/business.js +125 -1
- package/lib/Socket/communities.js +439 -0
- package/lib/Socket/groups.js +6 -0
- package/lib/Socket/index.js +2 -2
- package/lib/Socket/messages-recv.js +1 -0
- package/lib/Socket/messages-send.js +121 -2
- package/lib/Socket/socket.js +28 -1
- package/lib/Types/Newsletter.js +4 -0
- package/lib/Types/State.js +38 -0
- package/lib/Utils/decode-wa-message.js +4 -0
- package/lib/Utils/index.js +1 -0
- package/lib/Utils/messages-media.js +9 -4
- package/lib/Utils/messages.js +70 -109
- package/lib/Utils/process-message.js +5 -4
- package/lib/Utils/rich-messages.js +1205 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +26 -3
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +26 -0
- package/lib/WAUSync/Protocols/index.js +1 -0
- package/lib/WAUSync/USyncQuery.js +4 -0
- package/lib/WAUSync/USyncUser.js +8 -0
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
"use strict";
|
|
2
3
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -200,7 +201,7 @@ const makeMessagesSocket = (config) => {
|
|
|
200
201
|
}
|
|
201
202
|
return didFetchNewSession;
|
|
202
203
|
};
|
|
203
|
-
|
|
204
|
+
//
|
|
204
205
|
const sendPeerDataOperationMessage = async (pdoMessage) => {
|
|
205
206
|
var _a;
|
|
206
207
|
if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
@@ -597,6 +598,114 @@ const makeMessagesSocket = (config) => {
|
|
|
597
598
|
const giftedStatus = new GiftedStatus(Utils_1, waUploadToServer, relayMessage, config, sock);
|
|
598
599
|
|
|
599
600
|
const waitForMsgMediaUpdate = (0, Utils_1.bindWaitForEvent)(ev, 'messages.media-update');
|
|
601
|
+
// ============ RICH MESSAGE METHODS ============
|
|
602
|
+
/**
|
|
603
|
+
* Send a table as a rich (AI-forwarded-style) message.
|
|
604
|
+
* @param {string} jid
|
|
605
|
+
* @param {{ headers: string[], rows: string[][] } | string[][] | [string, string, string]} table
|
|
606
|
+
* Accepts any of:
|
|
607
|
+
* - { headers: string[], rows: string[][] }
|
|
608
|
+
* - a 2D array: [[headers...], [row1...], [row2...]]
|
|
609
|
+
* - legacy flat array: [title, "h1|h2", "r1c1|r1c2;;r2c1|r2c2"]
|
|
610
|
+
* @param {object} [quoted]
|
|
611
|
+
* @param {object} [options]
|
|
612
|
+
*/
|
|
613
|
+
const sendTable = async (jid, table, quoted, options = {}) => {
|
|
614
|
+
const { message, messageId } = Utils_1.generateTableContentV2(table, quoted, options);
|
|
615
|
+
await relayMessage(jid, message, { messageId });
|
|
616
|
+
return { message, messageId };
|
|
617
|
+
};
|
|
618
|
+
/**
|
|
619
|
+
* Send a list as a rich message.
|
|
620
|
+
*/
|
|
621
|
+
const sendList = async (jid, title, items, quoted, options = {}) => {
|
|
622
|
+
const { message, messageId } = Utils_1.generateListContent(title, items, quoted, options);
|
|
623
|
+
await relayMessage(jid, message, { messageId });
|
|
624
|
+
return { message, messageId };
|
|
625
|
+
};
|
|
626
|
+
/**
|
|
627
|
+
* Send a syntax-highlighted code block as a rich message.
|
|
628
|
+
* @param {string} jid
|
|
629
|
+
* @param {string} code
|
|
630
|
+
* @param {object} [quoted]
|
|
631
|
+
* @param {object} [options] - { language }
|
|
632
|
+
*/
|
|
633
|
+
const sendCodeBlock = async (jid, code, quoted, options = {}) => {
|
|
634
|
+
const { message, messageId } = Utils_1.generateCodeBlockContentV2(code, quoted, options);
|
|
635
|
+
await relayMessage(jid, message, { messageId });
|
|
636
|
+
return { message, messageId };
|
|
637
|
+
};
|
|
638
|
+
/**
|
|
639
|
+
* Send one or more links as a rich message.
|
|
640
|
+
*/
|
|
641
|
+
const sendLink = async (jid, text, links, quoted, options = {}) => {
|
|
642
|
+
const { message, messageId } = Utils_1.generateLinkContentV2(text, links, quoted, options);
|
|
643
|
+
await relayMessage(jid, message, { messageId });
|
|
644
|
+
return { message, messageId };
|
|
645
|
+
};
|
|
646
|
+
/**
|
|
647
|
+
* Send a LaTeX expression as text metadata (renders client-side).
|
|
648
|
+
*/
|
|
649
|
+
const sendLatex = async (jid, quoted, options = {}) => {
|
|
650
|
+
const { message, messageId } = Utils_1.generateLatexContent(quoted, options);
|
|
651
|
+
await relayMessage(jid, message, { messageId });
|
|
652
|
+
return { message, messageId };
|
|
653
|
+
};
|
|
654
|
+
/**
|
|
655
|
+
* Uploads a raw image buffer the same way updateCoverPhoto does, for use by the
|
|
656
|
+
* LaTeX-image rich message senders below (waUploadToServer expects a file path
|
|
657
|
+
* + its sha256, not a raw buffer).
|
|
658
|
+
*/
|
|
659
|
+
const uploadRawImageBuffer = async (buffer, mediaType = 'image') => {
|
|
660
|
+
const { fileSha256, filePath } = await Utils_1.getRawMediaUploadData(buffer, mediaType);
|
|
661
|
+
return waUploadToServer(filePath, {
|
|
662
|
+
fileEncSha256B64: fileSha256.toString('base64'),
|
|
663
|
+
mediaType
|
|
664
|
+
});
|
|
665
|
+
};
|
|
666
|
+
/**
|
|
667
|
+
* Send LaTeX expressions rendered to images. Requires a renderLatexToPng(expr) => { buffer, width, height }
|
|
668
|
+
* function to be supplied, since Baileys does not bundle a LaTeX renderer.
|
|
669
|
+
*/
|
|
670
|
+
const sendLatexImage = async (jid, quoted, options = {}, renderLatexToPng) => {
|
|
671
|
+
if (typeof renderLatexToPng !== 'function') {
|
|
672
|
+
throw new boom_1.Boom('sendLatexImage requires a renderLatexToPng(expression) function to be passed in');
|
|
673
|
+
}
|
|
674
|
+
const { message, messageId } = await Utils_1.generateLatexImageContent(quoted, options, uploadRawImageBuffer, renderLatexToPng);
|
|
675
|
+
await relayMessage(jid, message, { messageId });
|
|
676
|
+
return { message, messageId };
|
|
677
|
+
};
|
|
678
|
+
/**
|
|
679
|
+
* Send LaTeX expressions rendered inline as images. Requires the same renderLatexToPng function as sendLatexImage.
|
|
680
|
+
*/
|
|
681
|
+
const sendLatexInlineImage = async (jid, quoted, options = {}, renderLatexToPng) => {
|
|
682
|
+
if (typeof renderLatexToPng !== 'function') {
|
|
683
|
+
throw new boom_1.Boom('sendLatexInlineImage requires a renderLatexToPng(expression) function to be passed in');
|
|
684
|
+
}
|
|
685
|
+
const { message, messageId } = await Utils_1.generateLatexInlineImageContent(quoted, options, uploadRawImageBuffer, renderLatexToPng);
|
|
686
|
+
await relayMessage(jid, message, { messageId });
|
|
687
|
+
return { message, messageId };
|
|
688
|
+
};
|
|
689
|
+
/**
|
|
690
|
+
* Capture an outgoing/quoted rich (unified-response) message so it can later be re-sent verbatim.
|
|
691
|
+
*/
|
|
692
|
+
const captureUnifiedResponse = Utils_1.captureUnifiedResponse;
|
|
693
|
+
/**
|
|
694
|
+
* Re-send a previously captured unified response message.
|
|
695
|
+
*/
|
|
696
|
+
const sendUnifiedResponse = async (jid, quoted, captured) => {
|
|
697
|
+
const { message, messageId } = Utils_1.generateUnifiedResponseContent(quoted, captured);
|
|
698
|
+
await relayMessage(jid, message, { messageId });
|
|
699
|
+
return { message, messageId };
|
|
700
|
+
};
|
|
701
|
+
/**
|
|
702
|
+
* Send a rich message composed of multiple submessages (text/table/code/etc).
|
|
703
|
+
*/
|
|
704
|
+
const sendRichMessage = async (jid, submessages, quoted, options = {}) => {
|
|
705
|
+
const { message, messageId } = Utils_1.generateRichMessageContent(submessages, quoted);
|
|
706
|
+
await relayMessage(jid, message, { messageId });
|
|
707
|
+
return { message, messageId };
|
|
708
|
+
};
|
|
600
709
|
|
|
601
710
|
return {
|
|
602
711
|
...sock,
|
|
@@ -614,6 +723,16 @@ const makeMessagesSocket = (config) => {
|
|
|
614
723
|
sendPeerDataOperationMessage,
|
|
615
724
|
createParticipantNodes,
|
|
616
725
|
getUSyncDevices,
|
|
726
|
+
sendTable,
|
|
727
|
+
sendList,
|
|
728
|
+
sendCodeBlock,
|
|
729
|
+
sendLink,
|
|
730
|
+
sendLatex,
|
|
731
|
+
sendLatexImage,
|
|
732
|
+
sendLatexInlineImage,
|
|
733
|
+
captureUnifiedResponse,
|
|
734
|
+
sendUnifiedResponse,
|
|
735
|
+
sendRichMessage,
|
|
617
736
|
updateMediaMessage: async (message) => {
|
|
618
737
|
const content = (0, Utils_1.assertMediaContent)(message.message);
|
|
619
738
|
const mediaKey = content.mediaKey;
|
|
@@ -808,7 +927,7 @@ const makeMessagesSocket = (config) => {
|
|
|
808
927
|
|
|
809
928
|
return msg;
|
|
810
929
|
},
|
|
811
|
-
|
|
930
|
+
sendMessage: async (jid, content, options = {}) => {
|
|
812
931
|
var _a, _b, _c;
|
|
813
932
|
const userJid = authState.creds.me.id;
|
|
814
933
|
if (typeof content === 'object' &&
|
package/lib/Socket/socket.js
CHANGED
|
@@ -11,6 +11,7 @@ const Types_1 = require("../Types");
|
|
|
11
11
|
const Utils_1 = require("../Utils");
|
|
12
12
|
const WABinary_1 = require("../WABinary");
|
|
13
13
|
const Client_1 = require("./Client");
|
|
14
|
+
const mex_1 = require("./mex");
|
|
14
15
|
/**
|
|
15
16
|
* Connects to WA servers and performs:
|
|
16
17
|
* - simple queries (no retry mechanism, wait for connection establishment)
|
|
@@ -579,6 +580,30 @@ const makeSocket = (config) => {
|
|
|
579
580
|
}
|
|
580
581
|
Object.assign(creds, update);
|
|
581
582
|
});
|
|
583
|
+
/**
|
|
584
|
+
* Fetches your account's standing when it comes to restrictions.
|
|
585
|
+
* @returns Returns the state of the restrictions.
|
|
586
|
+
*/
|
|
587
|
+
const fetchAccountReachoutTimelock = async () => {
|
|
588
|
+
var _a, _b, _c;
|
|
589
|
+
const queryResult = await (0, mex_1.executeWMexQuery)({}, Types_1.QueryIds.REACHOUT_TIMELOCK, Types_1.XWAPaths.xwa2_fetch_account_reachout_timelock, query, generateMessageTag);
|
|
590
|
+
const result = {
|
|
591
|
+
isActive: !!(queryResult === null || queryResult === void 0 ? void 0 : queryResult.is_active),
|
|
592
|
+
timeEnforcementEnds: (queryResult === null || queryResult === void 0 ? void 0 : queryResult.time_enforcement_ends) && (queryResult === null || queryResult === void 0 ? void 0 : queryResult.time_enforcement_ends) !== '0'
|
|
593
|
+
? new Date(parseInt(queryResult.time_enforcement_ends, 10) * 1000)
|
|
594
|
+
: undefined,
|
|
595
|
+
enforcementType: (_a = queryResult === null || queryResult === void 0 ? void 0 : queryResult.enforcement_type) !== null && _a !== void 0 ? _a : Types_1.ReachoutTimelockEnforcementType.DEFAULT
|
|
596
|
+
};
|
|
597
|
+
ev.emit('connection.update', { reachoutTimeLock: result });
|
|
598
|
+
return result;
|
|
599
|
+
};
|
|
600
|
+
/**
|
|
601
|
+
* Fetches your account's new chat limits.
|
|
602
|
+
* @returns Returns the quota and the usage.
|
|
603
|
+
*/
|
|
604
|
+
const fetchNewChatMessageCap = async () => {
|
|
605
|
+
return (0, mex_1.executeWMexQuery)({ input: { type: 'INDIVIDUAL_NEW_CHAT_MSG' } }, Types_1.QueryIds.MESSAGE_CAPPING_INFO, Types_1.XWAPaths.xwa2_message_capping_info, query, generateMessageTag);
|
|
606
|
+
};
|
|
582
607
|
return {
|
|
583
608
|
type: 'md',
|
|
584
609
|
ws,
|
|
@@ -602,7 +627,9 @@ const makeSocket = (config) => {
|
|
|
602
627
|
requestPairingCode,
|
|
603
628
|
/** Waits for the connection to WA to reach a state */
|
|
604
629
|
waitForConnectionUpdate: (0, Utils_1.bindWaitForConnectionUpdate)(ev),
|
|
605
|
-
sendWAMBuffer
|
|
630
|
+
sendWAMBuffer,
|
|
631
|
+
fetchAccountReachoutTimelock,
|
|
632
|
+
fetchNewChatMessageCap
|
|
606
633
|
};
|
|
607
634
|
};
|
|
608
635
|
exports.makeSocket = makeSocket;
|
package/lib/Types/Newsletter.js
CHANGED
|
@@ -15,6 +15,8 @@ var XWAPaths;
|
|
|
15
15
|
XWAPaths["xwa2_newsletter_change_owner"] = "xwa2_newsletter_change_owner";
|
|
16
16
|
XWAPaths["xwa2_newsletter_demote"] = "xwa2_newsletter_demote";
|
|
17
17
|
XWAPaths["xwa2_newsletter_delete_v2"] = "xwa2_newsletter_delete_v2";
|
|
18
|
+
XWAPaths["xwa2_fetch_account_reachout_timelock"] = "xwa2_fetch_account_reachout_timelock";
|
|
19
|
+
XWAPaths["xwa2_message_capping_info"] = "xwa2_message_capping_info";
|
|
18
20
|
})(XWAPaths || (exports.XWAPaths = XWAPaths = {}));
|
|
19
21
|
var QueryIds;
|
|
20
22
|
(function (QueryIds) {
|
|
@@ -30,4 +32,6 @@ var QueryIds;
|
|
|
30
32
|
QueryIds["CHANGE_OWNER"] = "7341777602580933";
|
|
31
33
|
QueryIds["DEMOTE"] = "6551828931592903";
|
|
32
34
|
QueryIds["DELETE"] = "30062808666639665";
|
|
35
|
+
QueryIds["REACHOUT_TIMELOCK"] = "23983697327930364";
|
|
36
|
+
QueryIds["MESSAGE_CAPPING_INFO"] = "24503548349331633";
|
|
33
37
|
})(QueryIds || (exports.QueryIds = QueryIds = {}));
|
package/lib/Types/State.js
CHANGED
|
@@ -1,2 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NewChatMessageCappingMVStatusType = exports.NewChatMessageCappingStatusType = exports.ReachoutTimelockEnforcementType = void 0;
|
|
4
|
+
var ReachoutTimelockEnforcementType;
|
|
5
|
+
(function (ReachoutTimelockEnforcementType) {
|
|
6
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ALCOHOL"] = "BIZ_COMMERCE_VIOLATION_ALCOHOL";
|
|
7
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ADULT"] = "BIZ_COMMERCE_VIOLATION_ADULT";
|
|
8
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ANIMALS"] = "BIZ_COMMERCE_VIOLATION_ANIMALS";
|
|
9
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS"] = "BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS";
|
|
10
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DATING"] = "BIZ_COMMERCE_VIOLATION_DATING";
|
|
11
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS"] = "BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS";
|
|
12
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DRUGS"] = "BIZ_COMMERCE_VIOLATION_DRUGS";
|
|
13
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC"] = "BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC";
|
|
14
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_GAMBLING"] = "BIZ_COMMERCE_VIOLATION_GAMBLING";
|
|
15
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_HEALTHCARE"] = "BIZ_COMMERCE_VIOLATION_HEALTHCARE";
|
|
16
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY"] = "BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY";
|
|
17
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_SUPPLEMENTS"] = "BIZ_COMMERCE_VIOLATION_SUPPLEMENTS";
|
|
18
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_TOBACCO"] = "BIZ_COMMERCE_VIOLATION_TOBACCO";
|
|
19
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT"] = "BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT";
|
|
20
|
+
ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_WEAPONS"] = "BIZ_COMMERCE_VIOLATION_WEAPONS";
|
|
21
|
+
ReachoutTimelockEnforcementType["BIZ_QUALITY"] = "BIZ_QUALITY";
|
|
22
|
+
/** This means there is no restriction */
|
|
23
|
+
ReachoutTimelockEnforcementType["DEFAULT"] = "DEFAULT";
|
|
24
|
+
ReachoutTimelockEnforcementType["WEB_COMPANION_ONLY"] = "WEB_COMPANION_ONLY";
|
|
25
|
+
})(ReachoutTimelockEnforcementType || (exports.ReachoutTimelockEnforcementType = ReachoutTimelockEnforcementType = {}));
|
|
26
|
+
var NewChatMessageCappingStatusType;
|
|
27
|
+
(function (NewChatMessageCappingStatusType) {
|
|
28
|
+
NewChatMessageCappingStatusType["NONE"] = "NONE";
|
|
29
|
+
NewChatMessageCappingStatusType["FIRST_WARNING"] = "FIRST_WARNING";
|
|
30
|
+
NewChatMessageCappingStatusType["SECOND_WARNING"] = "SECOND_WARNING";
|
|
31
|
+
NewChatMessageCappingStatusType["CAPPED"] = "CAPPED";
|
|
32
|
+
})(NewChatMessageCappingStatusType || (exports.NewChatMessageCappingStatusType = NewChatMessageCappingStatusType = {}));
|
|
33
|
+
var NewChatMessageCappingMVStatusType;
|
|
34
|
+
(function (NewChatMessageCappingMVStatusType) {
|
|
35
|
+
NewChatMessageCappingMVStatusType["NOT_ELIGIBLE"] = "NOT_ELIGIBLE";
|
|
36
|
+
NewChatMessageCappingMVStatusType["NOT_ACTIVE"] = "NOT_ACTIVE";
|
|
37
|
+
NewChatMessageCappingMVStatusType["ACTIVE"] = "ACTIVE";
|
|
38
|
+
NewChatMessageCappingMVStatusType["ACTIVE_UPGRADE_AVAILABLE"] = "ACTIVE_UPGRADE_AVAILABLE";
|
|
39
|
+
})(NewChatMessageCappingMVStatusType || (exports.NewChatMessageCappingMVStatusType = NewChatMessageCappingMVStatusType = {}));
|
|
40
|
+
|
|
@@ -121,6 +121,9 @@ function decodeMessageNode(stanza, meId, meLid) {
|
|
|
121
121
|
const key = {
|
|
122
122
|
remoteJid: chatId,
|
|
123
123
|
remoteJidAlt: !(0, WABinary_1.isJidGroup)(chatId) ? addrCtx.senderAlt : undefined,
|
|
124
|
+
remoteJidUsername: !(0, WABinary_1.isJidGroup)(chatId)
|
|
125
|
+
? (stanza.attrs.peer_recipient_username || stanza.attrs.recipient_username)
|
|
126
|
+
: undefined,
|
|
124
127
|
fromMe,
|
|
125
128
|
id: msgId,
|
|
126
129
|
senderLid: senderLidValue,
|
|
@@ -129,6 +132,7 @@ function decodeMessageNode(stanza, meId, meLid) {
|
|
|
129
132
|
participantAlt: (0, WABinary_1.isJidGroup)(chatId) ? addrCtx.senderAlt : undefined,
|
|
130
133
|
participantPn: (_d = stanza === null || stanza === void 0 ? void 0 : stanza.attrs) === null || _d === void 0 ? void 0 : _d.participant_pn,
|
|
131
134
|
participantLid: (_e = stanza === null || stanza === void 0 ? void 0 : stanza.attrs) === null || _e === void 0 ? void 0 : _e.participant_lid,
|
|
135
|
+
participantUsername: stanza.attrs.participant ? stanza.attrs.participant_username : undefined,
|
|
132
136
|
addressingMode: addrCtx.addressingMode,
|
|
133
137
|
...(msgType === 'newsletter' && stanza.attrs.server_id ? { server_id: stanza.attrs.server_id } : {})
|
|
134
138
|
};
|
package/lib/Utils/index.js
CHANGED
|
@@ -31,3 +31,4 @@ __exportStar(require("./use-multi-file-auth-state"), exports);
|
|
|
31
31
|
__exportStar(require("./link-preview"), exports);
|
|
32
32
|
__exportStar(require("./event-buffer"), exports);
|
|
33
33
|
__exportStar(require("./process-message"), exports);
|
|
34
|
+
__exportStar(require("./rich-messages"), exports);
|
|
@@ -307,16 +307,21 @@ const toBuffer = async (stream) => {
|
|
|
307
307
|
};
|
|
308
308
|
exports.toBuffer = toBuffer;
|
|
309
309
|
const getStream = async (item, opts) => {
|
|
310
|
+
if (item === undefined || item === null) {
|
|
311
|
+
throw new boom_1.Boom('Media input is missing — expected a Buffer, { stream }, or { url } but got ' + item, { statusCode: 400 });
|
|
312
|
+
}
|
|
310
313
|
if (Buffer.isBuffer(item)) {
|
|
311
314
|
return { stream: (0, exports.toReadable)(item), type: 'buffer' };
|
|
312
315
|
}
|
|
313
|
-
if ('stream' in item) {
|
|
316
|
+
if (typeof item === 'object' && 'stream' in item && item.stream) {
|
|
314
317
|
return { stream: item.stream, type: 'readable' };
|
|
315
318
|
}
|
|
316
|
-
if (item
|
|
317
|
-
return
|
|
319
|
+
if (typeof item === 'object' && item.url) {
|
|
320
|
+
return item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')
|
|
321
|
+
? { stream: await (0, exports.getHttpStream)(item.url, opts), type: 'remote' }
|
|
322
|
+
: { stream: (0, fs_1.createReadStream)(item.url), type: 'file' };
|
|
318
323
|
}
|
|
319
|
-
|
|
324
|
+
throw new boom_1.Boom('Unsupported media input — expected a Buffer, { stream }, or { url } but got ' + JSON.stringify(item), { statusCode: 400 });
|
|
320
325
|
};
|
|
321
326
|
exports.getStream = getStream;
|
|
322
327
|
/** generates a thumbnail for a given media, if required */
|
package/lib/Utils/messages.js
CHANGED
|
@@ -621,136 +621,97 @@ else if ('paymentInvite' in message) {
|
|
|
621
621
|
else if ('stickerPack' in message) {
|
|
622
622
|
const { stickers, cover, name, publisher, packId, description } = message.stickerPack;
|
|
623
623
|
const { zip } = require("fflate");
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
zip(stickerData, (err, data) => {
|
|
648
|
-
if (err) {
|
|
649
|
-
reject(err);
|
|
650
|
-
} else {
|
|
651
|
-
resolve(Buffer.from(data));
|
|
624
|
+
if (!Array.isArray(stickers) || stickers.length === 0) {
|
|
625
|
+
throw new boom_1.Boom('Sticker pack must contain at least one sticker', { statusCode: 400 });
|
|
626
|
+
}
|
|
627
|
+
if (stickers.length > 120) {
|
|
628
|
+
throw new boom_1.Boom('Sticker pack exceeds the maximum limit of 120 stickers', { statusCode: 400 });
|
|
629
|
+
}
|
|
630
|
+
// WhatsApp requires every sticker to actually be WebP-encoded (not just named
|
|
631
|
+
// ".webp") — verified via magic bytes rather than trusting the file extension.
|
|
632
|
+
// We deliberately don't convert other formats here (that would require sharp or
|
|
633
|
+
// a webp-capable jimp build); pass in stickers that are already WebP.
|
|
634
|
+
const isWebPBuffer = (buf) => (buf.length >= 12 &&
|
|
635
|
+
buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 &&
|
|
636
|
+
buf[8] === 0x57 && buf[9] === 0x45 && buf[10] === 0x42 && buf[11] === 0x50);
|
|
637
|
+
const isAnimatedWebP = (buf) => {
|
|
638
|
+
let offset = 12;
|
|
639
|
+
while (offset < buf.length - 8) {
|
|
640
|
+
const fourCC = buf.toString('ascii', offset, offset + 4);
|
|
641
|
+
const chunkSize = buf.readUInt32LE(offset + 4);
|
|
642
|
+
if (fourCC === 'VP8X') {
|
|
643
|
+
const flagsOffset = offset + 8;
|
|
644
|
+
if (flagsOffset < buf.length && (buf[flagsOffset] & 0x02)) {
|
|
645
|
+
return true;
|
|
646
|
+
}
|
|
652
647
|
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
(0, messages_media_1.encryptedStream)(zipBuffer, "sticker-pack", {
|
|
660
|
-
logger: options.logger,
|
|
661
|
-
opts: options.options,
|
|
662
|
-
}),
|
|
663
|
-
(0, exports.prepareWAMessageMedia)({ image: coverBuffer }, { ...options, mediaTypeOverride: "image" })
|
|
664
|
-
]);
|
|
665
|
-
|
|
666
|
-
const stickerPackUploadResult = await options.upload(stickerPackUpload.encFilePath, {
|
|
667
|
-
fileEncSha256B64: stickerPackUpload.fileEncSha256.toString("base64"),
|
|
668
|
-
mediaType: "sticker-pack",
|
|
669
|
-
timeoutMs: options.mediaUploadTimeoutMs,
|
|
670
|
-
});
|
|
671
|
-
|
|
672
|
-
const coverImage = coverUpload.imageMessage;
|
|
673
|
-
const imageDataHash = (0, crypto_2.sha256)(coverBuffer).toString("base64");
|
|
674
|
-
const stickerPackId = packId || (0, generics_1.generateMessageIDV2)();
|
|
675
|
-
|
|
676
|
-
m.stickerPackMessage = {
|
|
677
|
-
name,
|
|
678
|
-
publisher,
|
|
679
|
-
stickerPackId,
|
|
680
|
-
packDescription: description,
|
|
681
|
-
stickerPackOrigin: WAProto_1.proto.Message.StickerPackMessage.StickerPackOrigin.THIRD_PARTY,
|
|
682
|
-
stickerPackSize: stickerPackUpload.fileLength,
|
|
683
|
-
stickers: stickerMetadata,
|
|
684
|
-
fileSha256: stickerPackUpload.fileSha256,
|
|
685
|
-
fileEncSha256: stickerPackUpload.fileEncSha256,
|
|
686
|
-
mediaKey: stickerPackUpload.mediaKey,
|
|
687
|
-
directPath: stickerPackUploadResult.directPath,
|
|
688
|
-
fileLength: stickerPackUpload.fileLength,
|
|
689
|
-
mediaKeyTimestamp: (0, generics_1.unixTimestampSeconds)(),
|
|
690
|
-
trayIconFileName: `${stickerPackId}.png`,
|
|
691
|
-
imageDataHash,
|
|
692
|
-
thumbnailDirectPath: coverImage.directPath,
|
|
693
|
-
thumbnailFileSha256: coverImage.fileSha256,
|
|
694
|
-
thumbnailFileEncSha256: coverImage.fileEncSha256,
|
|
695
|
-
thumbnailHeight: coverImage.height,
|
|
696
|
-
thumbnailWidth: coverImage.width,
|
|
648
|
+
else if (fourCC === 'ANIM' || fourCC === 'ANMF') {
|
|
649
|
+
return true;
|
|
650
|
+
}
|
|
651
|
+
offset += 8 + chunkSize + (chunkSize % 2);
|
|
652
|
+
}
|
|
653
|
+
return false;
|
|
697
654
|
};
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
const { zip } = require("fflate");
|
|
702
|
-
|
|
655
|
+
if (!cover) {
|
|
656
|
+
throw new boom_1.Boom('Sticker pack: a "cover" image (Buffer, { url } or { stream }) is required', { statusCode: 400 });
|
|
657
|
+
}
|
|
703
658
|
const stickerData = {};
|
|
704
|
-
const
|
|
705
|
-
const
|
|
659
|
+
const stickerMetadata = await Promise.all(stickers.map(async (s, i) => {
|
|
660
|
+
const stickerInput = s?.sticker ?? s;
|
|
661
|
+
if (!stickerInput) {
|
|
662
|
+
throw new boom_1.Boom(`Sticker pack: sticker at index ${i} is missing its media (expected { sticker: Buffer | { url } | { stream } })`, { statusCode: 400 });
|
|
663
|
+
}
|
|
664
|
+
const { stream } = await (0, messages_media_1.getStream)(stickerInput);
|
|
706
665
|
const buffer = await (0, messages_media_1.toBuffer)(stream);
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
666
|
+
if (!buffer || buffer.length === 0) {
|
|
667
|
+
throw new boom_1.Boom(`Sticker pack: sticker at index ${i} is empty`, { statusCode: 400 });
|
|
668
|
+
}
|
|
669
|
+
if (!isWebPBuffer(buffer)) {
|
|
670
|
+
throw new boom_1.Boom(`Sticker pack: sticker at index ${i} is not a valid WebP image. ` +
|
|
671
|
+
'Convert it to WebP before passing it in (e.g. with sharp or an external converter).', { statusCode: 400 });
|
|
672
|
+
}
|
|
673
|
+
const hash = (0, crypto_2.sha256)(buffer).toString('base64url');
|
|
674
|
+
const fileName = `${i.toString().padStart(2, '0')}_${hash}.webp`;
|
|
675
|
+
stickerData[fileName] = [new Uint8Array(buffer), { level: 6 }];
|
|
712
676
|
return {
|
|
713
677
|
fileName,
|
|
714
|
-
mimetype:
|
|
715
|
-
isAnimated: s.isAnimated
|
|
678
|
+
mimetype: 'image/webp',
|
|
679
|
+
isAnimated: typeof s.isAnimated === 'boolean' ? s.isAnimated : isAnimatedWebP(buffer),
|
|
716
680
|
isLottie: s.isLottie || false,
|
|
717
681
|
emojis: s.emojis || [],
|
|
718
|
-
accessibilityLabel: s.accessibilityLabel ||
|
|
682
|
+
accessibilityLabel: s.accessibilityLabel || ''
|
|
719
683
|
};
|
|
720
|
-
});
|
|
721
|
-
|
|
722
|
-
const stickerMetadata = await Promise.all(stickerPromises);
|
|
723
|
-
|
|
684
|
+
}));
|
|
724
685
|
const zipBuffer = await new Promise((resolve, reject) => {
|
|
725
686
|
zip(stickerData, (err, data) => {
|
|
726
687
|
if (err) {
|
|
727
688
|
reject(err);
|
|
728
|
-
}
|
|
689
|
+
}
|
|
690
|
+
else {
|
|
729
691
|
resolve(Buffer.from(data));
|
|
730
692
|
}
|
|
731
693
|
});
|
|
732
694
|
});
|
|
733
|
-
|
|
734
695
|
const coverBuffer = await (0, messages_media_1.toBuffer)((await (0, messages_media_1.getStream)(cover)).stream);
|
|
735
|
-
|
|
736
696
|
const [stickerPackUpload, coverUpload] = await Promise.all([
|
|
737
|
-
(0, messages_media_1.encryptedStream)(zipBuffer,
|
|
697
|
+
(0, messages_media_1.encryptedStream)(zipBuffer, 'sticker-pack', {
|
|
738
698
|
logger: options.logger,
|
|
739
|
-
opts: options.options
|
|
699
|
+
opts: options.options
|
|
740
700
|
}),
|
|
741
|
-
|
|
701
|
+
// prepareWAMessageMedia already resizes/re-encodes the cover to a JPEG via
|
|
702
|
+
// sharp if installed, falling back to jimp automatically (same helper the
|
|
703
|
+
// rest of this file already relies on for thumbnails/profile pictures) —
|
|
704
|
+
// no extra image library needed here.
|
|
705
|
+
(0, exports.prepareWAMessageMedia)({ image: coverBuffer }, { ...options, mediaTypeOverride: 'image' })
|
|
742
706
|
]);
|
|
743
|
-
|
|
744
707
|
const stickerPackUploadResult = await options.upload(stickerPackUpload.encFilePath, {
|
|
745
|
-
fileEncSha256B64: stickerPackUpload.fileEncSha256.toString(
|
|
746
|
-
mediaType:
|
|
747
|
-
timeoutMs: options.mediaUploadTimeoutMs
|
|
708
|
+
fileEncSha256B64: stickerPackUpload.fileEncSha256.toString('base64'),
|
|
709
|
+
mediaType: 'sticker-pack',
|
|
710
|
+
timeoutMs: options.mediaUploadTimeoutMs
|
|
748
711
|
});
|
|
749
|
-
|
|
750
712
|
const coverImage = coverUpload.imageMessage;
|
|
751
|
-
const imageDataHash = (0, crypto_2.sha256)(coverBuffer).toString(
|
|
713
|
+
const imageDataHash = (0, crypto_2.sha256)(coverBuffer).toString('base64');
|
|
752
714
|
const stickerPackId = packId || (0, generics_1.generateMessageIDV2)();
|
|
753
|
-
|
|
754
715
|
m.stickerPackMessage = {
|
|
755
716
|
name,
|
|
756
717
|
publisher,
|
|
@@ -765,15 +726,15 @@ else if ('paymentInvite' in message) {
|
|
|
765
726
|
directPath: stickerPackUploadResult.directPath,
|
|
766
727
|
fileLength: stickerPackUpload.fileLength,
|
|
767
728
|
mediaKeyTimestamp: (0, generics_1.unixTimestampSeconds)(),
|
|
768
|
-
trayIconFileName: `${stickerPackId}.
|
|
729
|
+
trayIconFileName: `${stickerPackId}.webp`,
|
|
769
730
|
imageDataHash,
|
|
770
731
|
thumbnailDirectPath: coverImage.directPath,
|
|
771
|
-
|
|
772
|
-
|
|
732
|
+
thumbnailSha256: coverImage.fileSha256,
|
|
733
|
+
thumbnailEncSha256: coverImage.fileEncSha256,
|
|
773
734
|
thumbnailHeight: coverImage.height,
|
|
774
|
-
thumbnailWidth: coverImage.width
|
|
735
|
+
thumbnailWidth: coverImage.width
|
|
775
736
|
};
|
|
776
|
-
}
|
|
737
|
+
}
|
|
777
738
|
|
|
778
739
|
|
|
779
740
|
|
|
@@ -244,13 +244,14 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
|
|
|
244
244
|
const jid = (_f = message.key) === null || _f === void 0 ? void 0 : _f.remoteJid;
|
|
245
245
|
//let actor = whatsappID (message.participant)
|
|
246
246
|
let participants;
|
|
247
|
-
const emitParticipantsUpdate = (action) => ev.emit('group-participants.update', { id: jid, author: message.participant, participants, action });
|
|
247
|
+
const emitParticipantsUpdate = (action) => { var _a, _b; return ev.emit('group-participants.update', { id: jid, author: message.participant, authorUsername: (_b = (_a = message.key) === null || _a === void 0 ? void 0 : _a.participantUsername) !== null && _b !== void 0 ? _b : undefined, participants, action }); };
|
|
248
248
|
const emitGroupUpdate = (update) => {
|
|
249
|
-
var _a;
|
|
250
|
-
ev.emit('groups.update', [{ id: jid, ...update, author: (_a = message.participant) !== null && _a !== void 0 ? _a : undefined }]);
|
|
249
|
+
var _a, _b, _c;
|
|
250
|
+
ev.emit('groups.update', [{ id: jid, ...update, author: (_a = message.participant) !== null && _a !== void 0 ? _a : undefined, authorUsername: (_c = (_b = message.key) === null || _b === void 0 ? void 0 : _b.participantUsername) !== null && _c !== void 0 ? _c : undefined }]);
|
|
251
251
|
};
|
|
252
252
|
const emitGroupRequestJoin = (participant, action, method) => {
|
|
253
|
-
|
|
253
|
+
var _a, _b;
|
|
254
|
+
ev.emit('group.join-request', { id: jid, author: message.participant, authorUsername: (_b = (_a = message.key) === null || _a === void 0 ? void 0 : _a.participantUsername) !== null && _b !== void 0 ? _b : undefined, participant, action, method: method });
|
|
254
255
|
};
|
|
255
256
|
const participantsIncludesMe = () => participants.find(jid => (0, WABinary_1.areJidsSameUser)(meId, jid));
|
|
256
257
|
switch (message.messageStubType) {
|