jagproject 26.3.28 → 26.3.30

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.
@@ -48,65 +48,6 @@ exports.PROCESSABLE_HISTORY_TYPES = [
48
48
  index_js_1.proto.HistorySync.HistorySyncType.NON_BLOCKING_DATA,
49
49
  index_js_1.proto.HistorySync.HistorySyncType.INITIAL_STATUS_V3
50
50
  ];
51
- const INTERACTIVE_MESSAGE_KEYS = ['interactiveMessage', 'buttonsMessage', 'listMessage', 'templateMessage'];
52
- const buildInteractiveMessageContextInfo = (existing) => ({
53
- ...(existing || {}),
54
- deviceListMetadata: existing?.deviceListMetadata || {},
55
- deviceListMetadataVersion: existing?.deviceListMetadataVersion || 2
56
- });
57
- const wrapInteractiveMessageForLegacyCompatibility = (msg) => {
58
- if (!msg || typeof msg !== 'object') {
59
- return msg;
60
- }
61
- const topLevelHasInteractive = INTERACTIVE_MESSAGE_KEYS.some(key => !!msg[key]);
62
- const wrappedViewOnceMessage = msg.viewOnceMessage?.message;
63
- const wrappedViewOnceV2Message = msg.viewOnceMessageV2?.message;
64
- const wrappedViewOnceV2ExtMessage = msg.viewOnceMessageV2Extension?.message;
65
- const wrappedMessage = wrappedViewOnceMessage || wrappedViewOnceV2Message || wrappedViewOnceV2ExtMessage;
66
- const wrappedHasInteractive = !!(wrappedMessage && INTERACTIVE_MESSAGE_KEYS.some(key => !!wrappedMessage[key]));
67
- if (wrappedHasInteractive) {
68
- const patchedWrappedMessage = {
69
- ...wrappedMessage,
70
- messageContextInfo: buildInteractiveMessageContextInfo(wrappedMessage.messageContextInfo)
71
- };
72
- if (wrappedViewOnceMessage) {
73
- return {
74
- ...msg,
75
- viewOnceMessage: {
76
- ...msg.viewOnceMessage,
77
- message: patchedWrappedMessage
78
- }
79
- };
80
- }
81
- if (wrappedViewOnceV2Message) {
82
- return {
83
- ...msg,
84
- viewOnceMessageV2: {
85
- ...msg.viewOnceMessageV2,
86
- message: patchedWrappedMessage
87
- }
88
- };
89
- }
90
- return {
91
- ...msg,
92
- viewOnceMessageV2Extension: {
93
- ...msg.viewOnceMessageV2Extension,
94
- message: patchedWrappedMessage
95
- }
96
- };
97
- }
98
- if (!topLevelHasInteractive) {
99
- return msg;
100
- }
101
- return {
102
- viewOnceMessage: {
103
- message: {
104
- ...msg,
105
- messageContextInfo: buildInteractiveMessageContextInfo(msg.messageContextInfo)
106
- }
107
- }
108
- };
109
- };
110
51
  exports.DEFAULT_CONNECTION_CONFIG = {
111
52
  version: exports.version,
112
53
  browser: browser_utils_js_1.Browsers.macOS('Chrome'),
@@ -123,7 +64,34 @@ exports.DEFAULT_CONNECTION_CONFIG = {
123
64
  auth: undefined,
124
65
  markOnlineOnConnect: true,
125
66
  syncFullHistory: true,
126
- patchMessageBeforeSending: msg => wrapInteractiveMessageForLegacyCompatibility(msg),
67
+ patchMessageBeforeSending: msg => {
68
+ const content = msg?.viewOnceMessage?.message || msg?.viewOnceMessageV2?.message || msg?.viewOnceMessageV2Extension?.message || msg;
69
+ const requiresPatch = !!(content?.buttonsMessage || content?.templateMessage || content?.listMessage || content?.interactiveMessage);
70
+ if (!requiresPatch)
71
+ return msg;
72
+ const wrapped = msg?.viewOnceMessage || msg?.viewOnceMessageV2 || msg?.viewOnceMessageV2Extension
73
+ ? msg
74
+ : {
75
+ viewOnceMessage: {
76
+ message: {
77
+ messageContextInfo: {
78
+ deviceListMetadataVersion: 2,
79
+ deviceListMetadata: {}
80
+ },
81
+ ...msg
82
+ }
83
+ }
84
+ };
85
+ const inner = wrapped?.viewOnceMessage?.message || wrapped?.viewOnceMessageV2?.message || wrapped?.viewOnceMessageV2Extension?.message;
86
+ if (inner) {
87
+ inner.messageContextInfo = {
88
+ deviceListMetadataVersion: 2,
89
+ deviceListMetadata: {},
90
+ ...(inner.messageContextInfo || {})
91
+ };
92
+ }
93
+ return wrapped;
94
+ },
127
95
  shouldSyncHistoryMessage: ({ syncType }) => {
128
96
  return syncType !== index_js_1.proto.HistorySync.HistorySyncType.FULL;
129
97
  },
@@ -499,6 +499,13 @@ const makeMessagesSocket = (config) => {
499
499
  messageContextInfo: message.messageContextInfo
500
500
  };
501
501
  const extraAttrs = {};
502
+ if ((message?.interactiveMessage || message?.buttonsMessage || message?.listMessage || message?.templateMessage)
503
+ && !additionalNodes?.some(node => node?.tag === 'biz')) {
504
+ const btnNode = getButtonArgs(message);
505
+ if (btnNode) {
506
+ additionalNodes = [...(additionalNodes || []), btnNode];
507
+ }
508
+ }
502
509
  if (participant) {
503
510
  if (!isGroup && !isStatus) {
504
511
  additionalAttributes = { ...additionalAttributes, device_fanout: 'false' };
@@ -107,7 +107,23 @@ const makeNewsletterSocket = (config) => {
107
107
  }
108
108
  };
109
109
  const result = await executeWMexQuery(variables, index_js_1.QueryIds.METADATA, index_js_1.XWAPaths.xwa2_newsletter_metadata);
110
- return parseNewsletterMetadata(result);
110
+ const meta = parseNewsletterMetadata(result);
111
+ if (!meta)
112
+ return meta;
113
+ const thread = meta.thread_metadata || {};
114
+ const normalizedName = typeof meta.name === 'string' ? meta.name : (meta.name?.text || thread.name?.text || '');
115
+ const normalizedSubscribers = typeof meta.subscribers === 'number'
116
+ ? meta.subscribers
117
+ : Number(meta.subscribers || thread.subscribers_count || 0);
118
+ const normalizedVerification = typeof meta.verification === 'string'
119
+ ? meta.verification
120
+ : (thread.verification || 'UNVERIFIED');
121
+ return {
122
+ ...meta,
123
+ name: normalizedName,
124
+ subscribers: Number.isFinite(normalizedSubscribers) ? normalizedSubscribers : 0,
125
+ verification: normalizedVerification
126
+ };
111
127
  },
112
128
  newsletterFollow: (jid) => {
113
129
  return executeWMexQuery({ newsletter_id: jid }, index_js_1.QueryIds.FOLLOW, index_js_1.XWAPaths.xwa2_newsletter_follow);
@@ -295,6 +295,9 @@ const toBuffer = async (stream) => {
295
295
  };
296
296
  exports.toBuffer = toBuffer;
297
297
  const getStream = async (item, opts) => {
298
+ if (item === undefined || item === null) {
299
+ throw new Error('Media input is undefined');
300
+ }
298
301
  if (Buffer.isBuffer(item)) {
299
302
  return { stream: (0, exports.toReadable)(item), type: 'buffer' };
300
303
  }
@@ -721,6 +721,7 @@ const generateWAMessageContent = async (message, options) => {
721
721
  else if ((0, exports.hasNonNullishProperty)(message, 'stickerPack')) {
722
722
  const { zip } = _require('fflate');
723
723
  const { stickers, cover, name, publisher, packId, description } = message.stickerPack;
724
+ const resolvedCover = cover || stickers?.[0]?.cover || stickers?.[0]?.data || stickers?.[0]?.sticker || stickers?.[0]?.image || stickers?.[0]?.url || stickers?.[0];
724
725
  // ── Validasi jumlah sticker ───────────────────────────────────────────
725
726
  if (stickers.length > 60) {
726
727
  throw new boom_1.Boom('Sticker pack exceeds the maximum limit of 60 stickers', { statusCode: 400 });
@@ -792,7 +793,10 @@ const generateWAMessageContent = async (message, options) => {
792
793
  const stickerMetadata = await Promise.all(stickerPromises);
793
794
  // ── Step 2: proses cover & masukkan ke dalam ZIP ──────────────────────
794
795
  const trayIconFileName = `${stickerPackId}.webp`;
795
- const coverBuffer = await (0, messages_media_js_1.toBuffer)((await (0, messages_media_js_1.getStream)(cover)).stream);
796
+ if (!resolvedCover) {
797
+ throw new boom_1.Boom('Sticker pack cover is missing and no fallback sticker was found', { statusCode: 400 });
798
+ }
799
+ const coverBuffer = await (0, messages_media_js_1.toBuffer)((await (0, messages_media_js_1.getStream)(resolvedCover)).stream);
796
800
  let coverWebpBuffer;
797
801
  if (isWebPBuffer(coverBuffer)) {
798
802
  coverWebpBuffer = coverBuffer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jagproject",
3
- "version": "26.03.28",
3
+ "version": "26.03.30",
4
4
  "update": "22 Maret 2026",
5
5
  "description": "WhatsApp Web API Library",
6
6
  "keywords": [