@hbmodsofc/baileys 2.4.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/LICENSE +1 -1
  2. package/README.MD +220 -1198
  3. package/WAProto/GenerateStatics.sh +4 -0
  4. package/WAProto/WAProto.proto +5619 -0
  5. package/engine-requirements.js +1 -1
  6. package/lib/Defaults/baileys-version.json +1 -1
  7. package/lib/Defaults/index.js +97 -122
  8. package/lib/Defaults/phonenumber_mcc.json +223 -0
  9. package/lib/Socket/Client/index.js +2 -3
  10. package/lib/Socket/Client/{web-socket-client.js → websocket.js} +54 -5
  11. package/lib/Socket/business.js +8 -2
  12. package/lib/Socket/chats.js +455 -288
  13. package/lib/Socket/communities.js +441 -0
  14. package/lib/Socket/groups.js +38 -23
  15. package/lib/Socket/hbmods.js +374 -406
  16. package/lib/Socket/index.js +43 -11
  17. package/lib/Socket/messages-recv.js +24 -69
  18. package/lib/Socket/messages-send.js +391 -419
  19. package/lib/Socket/newsletter.js +104 -190
  20. package/lib/Socket/socket.js +40 -54
  21. package/lib/Store/index.js +1 -3
  22. package/lib/Store/make-in-memory-store.js +27 -15
  23. package/lib/Store/make-ordered-dictionary.js +2 -2
  24. package/lib/Types/Label.js +1 -1
  25. package/lib/Types/LabelAssociation.js +1 -1
  26. package/lib/Types/Message.js +0 -2
  27. package/lib/Types/Newsletter.js +18 -38
  28. package/lib/Types/index.js +2 -2
  29. package/lib/Utils/async-iterable.js +41 -0
  30. package/lib/Utils/audioToBuffer.js +29 -0
  31. package/lib/Utils/auth-utils.js +6 -13
  32. package/lib/Utils/baileys-event-stream.js +1 -1
  33. package/lib/Utils/browser-utils.js +35 -0
  34. package/lib/Utils/business.js +2 -2
  35. package/lib/Utils/chat-utils.js +36 -35
  36. package/lib/Utils/crypto.js +71 -29
  37. package/lib/Utils/decode-wa-message.js +65 -56
  38. package/lib/Utils/event-buffer.js +13 -9
  39. package/lib/Utils/generics.js +88 -84
  40. package/lib/Utils/history.js +4 -6
  41. package/lib/Utils/index.js +3 -0
  42. package/lib/Utils/link-preview.js +34 -1
  43. package/lib/Utils/lt-hash.js +6 -6
  44. package/lib/Utils/message-retry-manager.js +128 -0
  45. package/lib/Utils/messages-media.js +340 -246
  46. package/lib/Utils/messages.js +329 -192
  47. package/lib/Utils/noise-handler.js +18 -23
  48. package/lib/Utils/process-message.js +108 -25
  49. package/lib/Utils/resolveJid.js +52 -0
  50. package/lib/Utils/signal.js +26 -26
  51. package/lib/Utils/streamToBuffer.js +15 -0
  52. package/lib/Utils/use-multi-file-auth-state.js +3 -0
  53. package/lib/Utils/validate-connection.js +1 -3
  54. package/lib/WABinary/constants.js +1276 -13
  55. package/lib/WABinary/decode.js +26 -13
  56. package/lib/WABinary/encode.js +137 -152
  57. package/lib/WABinary/generic-utils.js +37 -125
  58. package/lib/WABinary/jid-utils.js +28 -5
  59. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -1
  60. package/lib/index.js +53 -7
  61. package/package.json +112 -104
  62. package/lib/Defaults/index.d.ts +0 -53
  63. package/lib/Defaults/phonenumber-mcc.json +0 -223
  64. package/lib/Signal/Group/ciphertext-message.d.ts +0 -9
  65. package/lib/Signal/Group/group-session-builder.d.ts +0 -14
  66. package/lib/Signal/Group/group_cipher.d.ts +0 -17
  67. package/lib/Signal/Group/index.d.ts +0 -11
  68. package/lib/Signal/Group/keyhelper.d.ts +0 -10
  69. package/lib/Signal/Group/queue-job.d.ts +0 -1
  70. package/lib/Signal/Group/sender-chain-key.d.ts +0 -13
  71. package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -16
  72. package/lib/Signal/Group/sender-key-message.d.ts +0 -18
  73. package/lib/Signal/Group/sender-key-name.d.ts +0 -17
  74. package/lib/Signal/Group/sender-key-record.d.ts +0 -30
  75. package/lib/Signal/Group/sender-key-state.d.ts +0 -38
  76. package/lib/Signal/Group/sender-message-key.d.ts +0 -11
  77. package/lib/Signal/libsignal.d.ts +0 -3
  78. package/lib/Socket/Client/abstract-socket-client.d.ts +0 -17
  79. package/lib/Socket/Client/index.d.ts +0 -3
  80. package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
  81. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  82. package/lib/Socket/Client/web-socket-client.d.ts +0 -12
  83. package/lib/Socket/business.d.ts +0 -171
  84. package/lib/Socket/chats.d.ts +0 -267
  85. package/lib/Socket/groups.d.ts +0 -115
  86. package/lib/Socket/hbmods.d.ts +0 -254
  87. package/lib/Socket/index.d.ts +0 -173
  88. package/lib/Socket/messages-recv.d.ts +0 -161
  89. package/lib/Socket/messages-send.d.ts +0 -149
  90. package/lib/Socket/newsletter.d.ts +0 -134
  91. package/lib/Socket/registration.d.ts +0 -267
  92. package/lib/Socket/registration.js +0 -166
  93. package/lib/Socket/socket.d.ts +0 -43
  94. package/lib/Socket/usync.d.ts +0 -36
  95. package/lib/Store/index.d.ts +0 -3
  96. package/lib/Store/make-cache-manager-store.d.ts +0 -13
  97. package/lib/Store/make-cache-manager-store.js +0 -83
  98. package/lib/Store/make-in-memory-store.d.ts +0 -118
  99. package/lib/Store/make-ordered-dictionary.d.ts +0 -13
  100. package/lib/Store/object-repository.d.ts +0 -10
  101. package/lib/Types/Auth.d.ts +0 -110
  102. package/lib/Types/Call.d.ts +0 -13
  103. package/lib/Types/Chat.d.ts +0 -102
  104. package/lib/Types/Contact.d.ts +0 -19
  105. package/lib/Types/Events.d.ts +0 -157
  106. package/lib/Types/GroupMetadata.d.ts +0 -55
  107. package/lib/Types/Label.d.ts +0 -35
  108. package/lib/Types/LabelAssociation.d.ts +0 -29
  109. package/lib/Types/Message.d.ts +0 -273
  110. package/lib/Types/Newsletter.d.ts +0 -103
  111. package/lib/Types/Product.d.ts +0 -78
  112. package/lib/Types/Signal.d.ts +0 -57
  113. package/lib/Types/Socket.d.ts +0 -111
  114. package/lib/Types/State.d.ts +0 -27
  115. package/lib/Types/USync.d.ts +0 -25
  116. package/lib/Types/index.d.ts +0 -57
  117. package/lib/Utils/auth-utils.d.ts +0 -18
  118. package/lib/Utils/baileys-event-stream.d.ts +0 -16
  119. package/lib/Utils/business.d.ts +0 -22
  120. package/lib/Utils/chat-utils.d.ts +0 -71
  121. package/lib/Utils/crypto.d.ts +0 -41
  122. package/lib/Utils/decode-wa-message.d.ts +0 -19
  123. package/lib/Utils/event-buffer.d.ts +0 -35
  124. package/lib/Utils/generics.d.ts +0 -92
  125. package/lib/Utils/generics.js.bak +0 -433
  126. package/lib/Utils/history.d.ts +0 -15
  127. package/lib/Utils/index.d.ts +0 -17
  128. package/lib/Utils/link-preview.d.ts +0 -21
  129. package/lib/Utils/logger.d.ts +0 -4
  130. package/lib/Utils/lt-hash.d.ts +0 -12
  131. package/lib/Utils/make-mutex.d.ts +0 -7
  132. package/lib/Utils/messages-media.d.ts +0 -116
  133. package/lib/Utils/messages.d.ts +0 -77
  134. package/lib/Utils/noise-handler.d.ts +0 -21
  135. package/lib/Utils/process-message.d.ts +0 -41
  136. package/lib/Utils/signal.d.ts +0 -32
  137. package/lib/Utils/use-multi-file-auth-state.d.ts +0 -13
  138. package/lib/Utils/validate-connection.d.ts +0 -11
  139. package/lib/Utils/validate-connection.js.bak +0 -237
  140. package/lib/WABinary/constants.d.ts +0 -30
  141. package/lib/WABinary/decode.d.ts +0 -7
  142. package/lib/WABinary/encode.d.ts +0 -3
  143. package/lib/WABinary/generic-utils.d.ts +0 -17
  144. package/lib/WABinary/index.d.ts +0 -5
  145. package/lib/WABinary/jid-utils.d.ts +0 -31
  146. package/lib/WABinary/types.d.ts +0 -18
  147. package/lib/WAM/BinaryInfo.d.ts +0 -17
  148. package/lib/WAM/constants.d.ts +0 -38
  149. package/lib/WAM/encode.d.ts +0 -3
  150. package/lib/WAM/index.d.ts +0 -3
  151. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -9
  152. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -22
  153. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -12
  154. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -12
  155. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +0 -25
  156. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +0 -8
  157. package/lib/WAUSync/Protocols/index.d.ts +0 -4
  158. package/lib/WAUSync/USyncQuery.d.ts +0 -28
  159. package/lib/WAUSync/USyncUser.d.ts +0 -12
  160. package/lib/WAUSync/index.d.ts +0 -3
  161. package/lib/index.d.ts +0 -12
  162. /package/lib/Socket/Client/{abstract-socket-client.js → types.js} +0 -0
@@ -1,9 +1,10 @@
1
- "use strict";
1
+ "use strict";
2
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.assertMediaContent = exports.downloadMediaMessage = exports.aggregateMessageKeysNotFromMe = exports.getAggregateVotesInPollMessage = exports.updateMessageWithPollUpdate = exports.updateMessageWithReaction = exports.updateMessageWithReceipt = exports.getDevice = exports.extractMessageContent = exports.normalizeMessageContent = exports.getContentType = exports.generateWAMessage = exports.generateWAMessageFromContent = exports.generateWAMessageContent = exports.generateForwardMessageContent = exports.prepareDisappearingMessageSettingContent = exports.prepareWAMessageMedia = exports.generateLinkPreviewIfRequired = exports.extractUrlFromText = void 0;
6
+ exports.assertMediaContent = exports.downloadMediaMessage = exports.aggregateMessageKeysNotFromMe = exports.updateMessageWithPollUpdate = exports.updateMessageWithReaction = exports.updateMessageWithReceipt = exports.getDevice = exports.extractMessageContent = exports.normalizeMessageContent = exports.getContentType = exports.generateWAMessage = exports.generateWAMessageFromContent = exports.generateWAMessageContent = exports.generateForwardMessageContent = exports.prepareDisappearingMessageSettingContent = exports.prepareWAMessageMedia = exports.generateLinkPreviewIfRequired = exports.extractUrlFromText = void 0;
7
+ exports.getAggregateVotesInPollMessage = getAggregateVotesInPollMessage;
7
8
  const boom_1 = require("@hapi/boom");
8
9
  const axios_1 = __importDefault(require("axios"));
9
10
  const crypto_1 = require("crypto");
@@ -66,174 +67,46 @@ const assertColor = async (color) => {
66
67
  }
67
68
  };
68
69
  const prepareWAMessageMedia = async (message, options) => {
69
- const logger = options.logger;
70
- let mediaType;
71
- for (const key of Defaults_1.MEDIA_KEYS) {
72
- if (key in message) {
73
- mediaType = key;
74
- }
75
- }
76
- if (!mediaType) {
77
- throw new boom_1.Boom('Invalid media type', {
78
- statusCode: 400
79
- });
80
- }
70
+ let mediaType = MEDIA_KEYS.find(key => key in message);
71
+ if (!mediaType) throw new Boom('Invalid media type', { statusCode: 400 });
81
72
 
82
- const uploadData = {
83
- ...message,
84
- ...(message.annotations ? {
85
- annotations: message.annotations
86
- } : {
87
- annotations: [
88
- {
89
- polygonVertices: [
90
- {
91
- x: 60.71664810180664,
92
- y: -36.39784622192383
93
- },
94
- {
95
- x: -16.710189819335938,
96
- y: 49.263675689697266
97
- },
98
- {
99
- x: -56.585853576660156,
100
- y: 37.85963439941406
101
- },
102
- {
103
- x: 20.840980529785156,
104
- y: -47.80188751220703
105
- }
106
- ],
107
- newsletter: {
108
- newsletterJid: "120363420249672073@newsletter",
109
- serverMessageId: 0,
110
- newsletterName: "kyuu ilysm",
111
- contentType: "UPDATE",
112
- }
113
- }
114
- ]
115
- }),
116
- media: message[mediaType]
117
- };
73
+ const uploadData = { ...message, media: message[mediaType] };
118
74
  delete uploadData[mediaType];
119
- const cacheableKey = typeof uploadData.media === 'object' &&
120
- ('url' in uploadData.media) &&
121
- !!uploadData.media.url &&
122
- !!options.mediaCache && (
123
- mediaType + ':' + uploadData.media.url.toString());
124
-
125
- if (mediaType === 'document' && !uploadData.fileName) {
126
- uploadData.fileName = 'file';
127
- }
128
-
129
- if (!uploadData.mimetype) {
130
- uploadData.mimetype = MIMETYPE_MAP[mediaType];
131
- }
75
+
76
+ const cacheableKey = typeof uploadData.media === 'object' && 'url' in uploadData.media && uploadData.media.url && options.mediaCache
77
+ ? `${mediaType}:${uploadData.media.url.toString()}` : null;
78
+
79
+ if (mediaType === 'document' && !uploadData.fileName) uploadData.fileName = 'file';
80
+ if (!uploadData.mimetype) uploadData.mimetype = MIMETYPE_MAP[mediaType];
132
81
 
133
82
  if (cacheableKey) {
134
- const mediaBuff = options.mediaCache.get(cacheableKey);
135
- if (mediaBuff) {
136
- logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'got media cache hit');
137
- const obj = Types_1.WAProto.Message.decode(mediaBuff);
138
- const key = `${mediaType}Message`;
139
- Object.assign(obj[key], { ...uploadData, media: undefined });
83
+ const cached = await options.mediaCache?.get(cacheableKey);
84
+ if (cached) {
85
+ const obj = proto.Message.decode(cached);
86
+ Object.assign(obj[`${mediaType}Message`], { ...uploadData, media: undefined });
140
87
  return obj;
141
88
  }
142
89
  }
143
90
 
144
- const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
145
- const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
146
- (typeof uploadData['jpegThumbnail'] === 'undefined');
147
- const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
148
- const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
149
- const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
150
-
151
- const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, opusConverted } = await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
152
- logger,
153
- saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
154
- opts: options.options,
155
- isPtt: uploadData.ptt,
156
- forceOpus: (mediaType === "audio" && uploadData.mimetype && uploadData.mimetype.includes('opus'))
157
- });
158
-
159
- if (mediaType === 'audio' && opusConverted) {
160
- uploadData.mimetype = 'audio/ogg; codecs=opus';
161
- }
162
-
163
- const fileEncSha256B64 = (options.newsletter ? fileSha256 : fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256).toString('base64');
164
-
165
- const [{ mediaUrl, directPath, handle }] = await Promise.all([
166
- (async () => {
167
- const result = await options.upload(encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs });
168
- logger === null || logger === void 0 ? void 0 : logger.debug({ mediaType, cacheableKey }, 'uploaded media');
169
- return result;
170
- })(),
171
- (async () => {
172
- try {
173
- if (requiresThumbnailComputation) {
174
- const { thumbnail, originalImageDimensions } = await (0, messages_media_1.generateThumbnail)(bodyPath, mediaType, options);
175
- uploadData.jpegThumbnail = thumbnail;
176
- if (!uploadData.width && originalImageDimensions) {
177
- uploadData.width = originalImageDimensions.width;
178
- uploadData.height = originalImageDimensions.height;
179
- logger === null || logger === void 0 ? void 0 : logger.debug('set dimensions');
180
- }
181
- logger === null || logger === void 0 ? void 0 : logger.debug('generated thumbnail');
182
- }
183
- if (requiresDurationComputation) {
184
- uploadData.seconds = await (0, messages_media_1.getAudioDuration)(bodyPath);
185
- logger === null || logger === void 0 ? void 0 : logger.debug('computed audio duration');
186
- }
187
- if (requiresWaveformProcessing) {
188
- uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(bodyPath, logger);
189
- logger === null || logger === void 0 ? void 0 : logger.debug('processed waveform');
190
- }
191
- if (requiresAudioBackground) {
192
- uploadData.backgroundArgb = await assertColor(options.backgroundColor);
193
- logger === null || logger === void 0 ? void 0 : logger.debug('computed backgroundColor audio status');
194
- }
195
- }
196
- catch (error) {
197
- logger === null || logger === void 0 ? void 0 : logger.warn({ trace: error.stack }, 'failed to obtain extra info');
198
- }
199
- })(),
200
- ])
201
- .finally(async () => {
202
- if (!Buffer.isBuffer(encWriteStream)) {
203
- encWriteStream.destroy();
204
- }
205
-
206
- if (didSaveToTmpPath && bodyPath) {
207
- await fs_1.promises.unlink(bodyPath);
208
- logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp files');
209
- }
210
- });
211
-
212
- const obj = Types_1.WAProto.Message.fromObject({
213
- [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
214
- url: handle ? undefined : mediaUrl,
215
- directPath,
216
- mediaKey: mediaKey,
217
- fileEncSha256: fileEncSha256,
218
- fileSha256,
219
- fileLength,
220
- mediaKeyTimestamp: handle ? undefined : (0, generics_1.unixTimestampSeconds)(),
221
- ...uploadData,
222
- media: undefined
223
- })
224
- });
225
-
226
- if (uploadData.ptv) {
227
- obj.ptvMessage = obj.videoMessage;
228
- delete obj.videoMessage;
229
- }
230
-
231
- if (cacheableKey) {
232
- logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
233
- options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
91
+ if (isJidNewsletter(options.jid)) {
92
+ const { filePath, fileSha256, fileLength } = await getRawMediaUploadData(uploadData.media, options.mediaTypeOverride || mediaType, options.logger);
93
+ const { mediaUrl, directPath } = await options.upload(filePath, {
94
+ fileEncSha256B64: fileSha256.toString('base64'),
95
+ mediaType, timeoutMs: options.mediaUploadTimeoutMs
96
+ });
97
+ await fs.unlink(filePath);
98
+ const obj = WAProto.Message.fromObject({
99
+ [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
100
+ url: mediaUrl, directPath, fileSha256, fileLength, ...uploadData, media: undefined
101
+ })
102
+ });
103
+ if (uploadData.ptv) { obj.ptvMessage = obj.videoMessage; delete obj.videoMessage; }
104
+ if (obj.stickerMessage) obj.stickerMessage.stickerSentTs = Date.now();
105
+ if (cacheableKey) await options.mediaCache?.set(cacheableKey, WAProto.Message.encode(obj).finish());
106
+ return obj;
234
107
  }
235
108
 
236
- return obj;
109
+ return createMediaMessage(uploadData, mediaType, options, cacheableKey);
237
110
  };
238
111
  exports.prepareWAMessageMedia = prepareWAMessageMedia;
239
112
  const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
@@ -283,8 +156,8 @@ const generateForwardMessageContent = (message, forceForward) => {
283
156
  };
284
157
  exports.generateForwardMessageContent = generateForwardMessageContent;
285
158
  const generateWAMessageContent = async (message, options) => {
286
- var _a;
287
- var _b;
159
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
160
+ var _p, _q;
288
161
  let m = {};
289
162
  if ('text' in message) {
290
163
  const extContent = { text: message.text };
@@ -293,7 +166,6 @@ const generateWAMessageContent = async (message, options) => {
293
166
  urlInfo = await (0, exports.generateLinkPreviewIfRequired)(message.text, options.getUrlInfo, options.logger);
294
167
  }
295
168
  if (urlInfo) {
296
- extContent.canonicalUrl = urlInfo['canonical-url'];
297
169
  extContent.matchedText = urlInfo['matched-text'];
298
170
  extContent.jpegThumbnail = urlInfo.jpegThumbnail;
299
171
  extContent.description = urlInfo.description;
@@ -354,6 +226,54 @@ const generateWAMessageContent = async (message, options) => {
354
226
  message.disappearingMessagesInChat;
355
227
  m = (0, exports.prepareDisappearingMessageSettingContent)(exp);
356
228
  }
229
+ else if ('groupInvite' in message) {
230
+ m.groupInviteMessage = {};
231
+ m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
232
+ m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
233
+ m.groupInviteMessage.caption = message.groupInvite.text;
234
+ m.groupInviteMessage.groupJid = message.groupInvite.jid;
235
+ m.groupInviteMessage.groupName = message.groupInvite.subject;
236
+ //TODO: use built-in interface and get disappearing mode info etc.
237
+ //TODO: cache / use store!?
238
+ if (options.getProfilePicUrl) {
239
+ const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
240
+ if (pfpUrl) {
241
+ const resp = await axios_1.default.get(pfpUrl, { responseType: 'arraybuffer' });
242
+ if (resp.status === 200) {
243
+ m.groupInviteMessage.jpegThumbnail = resp.data;
244
+ }
245
+ }
246
+ }
247
+ }
248
+ else if ('pin' in message) {
249
+ m.pinInChatMessage = {};
250
+ m.messageContextInfo = {};
251
+ m.pinInChatMessage.key = message.pin;
252
+ m.pinInChatMessage.type = message.type;
253
+ m.pinInChatMessage.senderTimestampMs = Date.now();
254
+ m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0;
255
+ }
256
+ else if ('keep' in message) {
257
+ m.keepInChatMessage = {};
258
+ m.keepInChatMessage.key = message.keep;
259
+ m.keepInChatMessage.keepType = message.type;
260
+ m.keepInChatMessage.timestampMs = Date.now();
261
+ }
262
+ else if ('call' in message) {
263
+ m = {
264
+ scheduledCallCreationMessage: {
265
+ scheduledTimestampMs: (_a = message.call.time) !== null && _a !== void 0 ? _a : Date.now(),
266
+ callType: (_b = message.call.type) !== null && _b !== void 0 ? _b : 1,
267
+ title: message.call.title
268
+ }
269
+ };
270
+ }
271
+ else if ('paymentInvite' in message) {
272
+ m.paymentInviteMessage = {
273
+ serviceType: message.paymentInvite.type,
274
+ expiryTimestamp: message.paymentInvite.expiry
275
+ };
276
+ }
357
277
  else if ('buttonReply' in message) {
358
278
  switch (message.type) {
359
279
  case 'template':
@@ -372,6 +292,10 @@ const generateWAMessageContent = async (message, options) => {
372
292
  break;
373
293
  }
374
294
  }
295
+ else if ('ptv' in message && message.ptv) {
296
+ const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
297
+ m.ptvMessage = videoMessage;
298
+ }
375
299
  else if ('product' in message) {
376
300
  const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
377
301
  m.productMessage = Types_1.WAProto.Message.ProductMessage.fromObject({
@@ -382,11 +306,27 @@ const generateWAMessageContent = async (message, options) => {
382
306
  }
383
307
  });
384
308
  }
309
+ else if ('order' in message) {
310
+ m.orderMessage = Types_1.WAProto.Message.OrderMessage.fromObject({
311
+ orderId: message.order.id,
312
+ thumbnail: message.order.thumbnail,
313
+ itemCount: message.order.itemCount,
314
+ status: message.order.status,
315
+ surface: message.order.surface,
316
+ orderTitle: message.order.title,
317
+ message: message.order.text,
318
+ sellerJid: message.order.seller,
319
+ token: message.order.token,
320
+ totalAmount1000: message.order.amount,
321
+ totalCurrencyCode: message.order.currency
322
+ });
323
+ }
385
324
  else if ('listReply' in message) {
386
325
  m.listResponseMessage = { ...message.listReply };
387
326
  }
388
327
  else if ('poll' in message) {
389
- (_b = message.poll).selectableCount || (_b.selectableCount = 0);
328
+ (_p = message.poll).selectableCount || (_p.selectableCount = 0);
329
+ (_q = message.poll).toAnnouncementGroup || (_q.toAnnouncementGroup = false);
390
330
  if (!Array.isArray(message.poll.values)) {
391
331
  throw new boom_1.Boom('Invalid poll values', { statusCode: 400 });
392
332
  }
@@ -398,11 +338,72 @@ const generateWAMessageContent = async (message, options) => {
398
338
  // encKey
399
339
  messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32),
400
340
  };
401
- m.pollCreationMessage = {
341
+ const pollCreationMessage = {
402
342
  name: message.poll.name,
403
343
  selectableOptionsCount: message.poll.selectableCount,
404
344
  options: message.poll.values.map(optionName => ({ optionName })),
405
345
  };
346
+ if (message.poll.toAnnouncementGroup) {
347
+ // poll v2 is for community announcement groups (single select and multiple)
348
+ m.pollCreationMessageV2 = pollCreationMessage;
349
+ }
350
+ else {
351
+ if (message.poll.selectableCount === 1) {
352
+ // poll v3 is for single select polls
353
+ m.pollCreationMessageV3 = pollCreationMessage;
354
+ }
355
+ else {
356
+ // poll for multiple choice polls
357
+ m.pollCreationMessage = pollCreationMessage;
358
+ }
359
+ }
360
+ }
361
+ else if ('event' in message) {
362
+ m.messageContextInfo = {
363
+ messageSecret: message.event.messageSecret || (0, crypto_1.randomBytes)(32),
364
+ };
365
+ m.eventMessage = { ...message.event };
366
+ }
367
+ else if ('inviteAdmin' in message) {
368
+ m.newsletterAdminInviteMessage = {};
369
+ m.newsletterAdminInviteMessage.inviteExpiration = message.inviteAdmin.inviteExpiration;
370
+ m.newsletterAdminInviteMessage.caption = message.inviteAdmin.text;
371
+ m.newsletterAdminInviteMessage.newsletterJid = message.inviteAdmin.jid;
372
+ m.newsletterAdminInviteMessage.newsletterName = message.inviteAdmin.subject;
373
+ m.newsletterAdminInviteMessage.jpegThumbnail = message.inviteAdmin.thumbnail;
374
+ }
375
+ else if ('requestPayment' in message) {
376
+ const sticker = ((_c = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _c === void 0 ? void 0 : _c.sticker) ?
377
+ await (0, exports.prepareWAMessageMedia)({ sticker: (_d = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _d === void 0 ? void 0 : _d.sticker, ...options }, options)
378
+ : null;
379
+ let notes = {};
380
+ if ((_e = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _e === void 0 ? void 0 : _e.sticker) {
381
+ notes = {
382
+ stickerMessage: {
383
+ ...sticker === null || sticker === void 0 ? void 0 : sticker.stickerMessage,
384
+ contextInfo: (_f = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _f === void 0 ? void 0 : _f.contextInfo
385
+ }
386
+ };
387
+ }
388
+ else if (message.requestPayment.note) {
389
+ notes = {
390
+ extendedTextMessage: {
391
+ text: message.requestPayment.note,
392
+ contextInfo: (_g = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _g === void 0 ? void 0 : _g.contextInfo,
393
+ }
394
+ };
395
+ }
396
+ else {
397
+ throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
398
+ }
399
+ m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
400
+ expiryTimestamp: message.requestPayment.expiry,
401
+ amount1000: message.requestPayment.amount,
402
+ currencyCodeIso4217: message.requestPayment.currency,
403
+ requestFrom: message.requestPayment.from,
404
+ noteMessage: { ...notes },
405
+ background: (_h = message.requestPayment.background) !== null && _h !== void 0 ? _h : null,
406
+ });
406
407
  }
407
408
  else if ('sharePhoneNumber' in message) {
408
409
  m.protocolMessage = {
@@ -412,6 +413,14 @@ const generateWAMessageContent = async (message, options) => {
412
413
  else if ('requestPhoneNumber' in message) {
413
414
  m.requestPhoneNumberMessage = {};
414
415
  }
416
+ else if ('album' in message) {
417
+ const imageMessages = message.album.filter(item => 'image' in item);
418
+ const videoMessages = message.album.filter(item => 'video' in item);
419
+ m.albumMessage = WAProto_1.proto.Message.AlbumMessage.fromObject({
420
+ expectedImageCount: imageMessages.length,
421
+ expectedVideoCount: videoMessages.length,
422
+ });
423
+ }
415
424
  else {
416
425
  m = await (0, exports.prepareWAMessageMedia)(message, options);
417
426
  }
@@ -431,14 +440,24 @@ const generateWAMessageContent = async (message, options) => {
431
440
  buttonsMessage.headerType = ButtonType[type];
432
441
  Object.assign(buttonsMessage, m);
433
442
  }
443
+ if ('title' in message && !!message.title) {
444
+ buttonsMessage.text = message.title,
445
+ buttonsMessage.headerType = ButtonType.TEXT;
446
+ }
434
447
  if ('footer' in message && !!message.footer) {
435
448
  buttonsMessage.footerText = message.footer;
436
449
  }
450
+ if ('contextInfo' in message && !!message.contextInfo) {
451
+ buttonsMessage.contextInfo = message.contextInfo;
452
+ }
453
+ if ('mentions' in message && !!message.mentions) {
454
+ buttonsMessage.contextInfo = { mentionedJid: message.mentions };
455
+ }
437
456
  m = { buttonsMessage };
438
457
  }
439
458
  else if ('templateButtons' in message && !!message.templateButtons) {
440
459
  const msg = {
441
- hydratedButtons: message.templateButtons
460
+ hydratedButtons: message.hasOwnProperty("templateButtons") ? message.templateButtons : message.templateButtons
442
461
  };
443
462
  if ('text' in message) {
444
463
  msg.hydratedContentText = message.text;
@@ -470,10 +489,97 @@ const generateWAMessageContent = async (message, options) => {
470
489
  };
471
490
  m = { listMessage };
472
491
  }
492
+ if ('interactiveButtons' in message && !!message.interactiveButtons) {
493
+ const interactiveMessage = {
494
+ nativeFlowMessage: Types_1.WAProto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
495
+ buttons: message.interactiveButtons,
496
+ })
497
+ };
498
+ if ('text' in message) {
499
+ interactiveMessage.body = {
500
+ text: message.text
501
+ };
502
+ }
503
+ else if ('caption' in message) {
504
+ interactiveMessage.body = {
505
+ text: message.caption
506
+ };
507
+ interactiveMessage.header = {
508
+ title: message.title,
509
+ subtitle: message.subtitle,
510
+ hasMediaAttachment: (_j = message === null || message === void 0 ? void 0 : message.media) !== null && _j !== void 0 ? _j : false,
511
+ };
512
+ Object.assign(interactiveMessage.header, m);
513
+ }
514
+ if ('footer' in message && !!message.footer) {
515
+ interactiveMessage.footer = {
516
+ text: message.footer
517
+ };
518
+ }
519
+ if ('title' in message && !!message.title) {
520
+ interactiveMessage.header = {
521
+ title: message.title,
522
+ subtitle: message.subtitle,
523
+ hasMediaAttachment: (_k = message === null || message === void 0 ? void 0 : message.media) !== null && _k !== void 0 ? _k : false,
524
+ };
525
+ Object.assign(interactiveMessage.header, m);
526
+ }
527
+ if ('contextInfo' in message && !!message.contextInfo) {
528
+ interactiveMessage.contextInfo = message.contextInfo;
529
+ }
530
+ if ('mentions' in message && !!message.mentions) {
531
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
532
+ }
533
+ m = { interactiveMessage };
534
+ }
535
+ if ('shop' in message && !!message.shop) {
536
+ const interactiveMessage = {
537
+ shopStorefrontMessage: Types_1.WAProto.Message.InteractiveMessage.ShopMessage.fromObject({
538
+ surface: message.shop,
539
+ id: message.id
540
+ })
541
+ };
542
+ if ('text' in message) {
543
+ interactiveMessage.body = {
544
+ text: message.text
545
+ };
546
+ }
547
+ else if ('caption' in message) {
548
+ interactiveMessage.body = {
549
+ text: message.caption
550
+ };
551
+ interactiveMessage.header = {
552
+ title: message.title,
553
+ subtitle: message.subtitle,
554
+ hasMediaAttachment: (_l = message === null || message === void 0 ? void 0 : message.media) !== null && _l !== void 0 ? _l : false,
555
+ };
556
+ Object.assign(interactiveMessage.header, m);
557
+ }
558
+ if ('footer' in message && !!message.footer) {
559
+ interactiveMessage.footer = {
560
+ text: message.footer
561
+ };
562
+ }
563
+ if ('title' in message && !!message.title) {
564
+ interactiveMessage.header = {
565
+ title: message.title,
566
+ subtitle: message.subtitle,
567
+ hasMediaAttachment: (_m = message === null || message === void 0 ? void 0 : message.media) !== null && _m !== void 0 ? _m : false,
568
+ };
569
+ Object.assign(interactiveMessage.header, m);
570
+ }
571
+ if ('contextInfo' in message && !!message.contextInfo) {
572
+ interactiveMessage.contextInfo = message.contextInfo;
573
+ }
574
+ if ('mentions' in message && !!message.mentions) {
575
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
576
+ }
577
+ m = { interactiveMessage };
578
+ }
473
579
  if ('viewOnce' in message && !!message.viewOnce) {
474
580
  m = { viewOnceMessage: { message: m } };
475
581
  }
476
- if ('mentions' in message && ((_a = message.mentions) === null || _a === void 0 ? void 0 : _a.length)) {
582
+ if ('mentions' in message && ((_o = message.mentions) === null || _o === void 0 ? void 0 : _o.length)) {
477
583
  const [messageType] = Object.keys(m);
478
584
  m[messageType].contextInfo = m[messageType] || {};
479
585
  m[messageType].contextInfo.mentionedJid = message.mentions;
@@ -506,26 +612,29 @@ const generateWAMessageFromContent = (jid, message, options) => {
506
612
  const key = (0, exports.getContentType)(innerMessage);
507
613
  const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp);
508
614
  const { quoted, userJid } = options;
509
- if (quoted && !(0, WABinary_1.isJidNewsLetter)(jid)) {
615
+ // only set quoted if isn't a newsletter message
616
+ if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
510
617
  const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid);
511
618
  let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message);
512
619
  const msgType = (0, exports.getContentType)(quotedMsg);
513
620
  // strip any redundant properties
514
- quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
515
- const quotedContent = quotedMsg[msgType];
516
- if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
517
- delete quotedContent.contextInfo;
518
- }
519
- const contextInfo = innerMessage[key].contextInfo || {};
520
- contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
521
- contextInfo.stanzaId = quoted.key.id;
522
- contextInfo.quotedMessage = quotedMsg;
523
- // if a participant is quoted, then it must be a group
524
- // hence, remoteJid of group must also be entered
525
- if (jid !== quoted.key.remoteJid) {
526
- contextInfo.remoteJid = quoted.key.remoteJid;
527
- }
528
- innerMessage[key].contextInfo = contextInfo;
621
+ if (quotedMsg) {
622
+ quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
623
+ const quotedContent = quotedMsg[msgType];
624
+ if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
625
+ delete quotedContent.contextInfo;
626
+ }
627
+ const contextInfo = innerMessage[key].contextInfo || {};
628
+ contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
629
+ contextInfo.stanzaId = quoted.key.id;
630
+ contextInfo.quotedMessage = quotedMsg;
631
+ // if a participant is quoted, then it must be a group
632
+ // hence, remoteJid of group must also be entered
633
+ if (jid !== quoted.key.remoteJid) {
634
+ contextInfo.remoteJid = quoted.key.remoteJid;
635
+ }
636
+ innerMessage[key].contextInfo = contextInfo;
637
+ }
529
638
  }
530
639
  if (
531
640
  // if we want to send a disappearing message
@@ -535,7 +644,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
535
644
  // already not converted to disappearing message
536
645
  key !== 'ephemeralMessage' &&
537
646
  // newsletter not accept disappearing messages
538
- !(0, WABinary_1.isJidNewsLetter)(jid)) {
647
+ !(0, WABinary_1.isJidNewsletter)(jid)) {
539
648
  innerMessage[key].contextInfo = {
540
649
  ...(innerMessage[key].contextInfo || {}),
541
650
  expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL,
@@ -547,7 +656,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
547
656
  key: {
548
657
  remoteJid: jid,
549
658
  fromMe: true,
550
- id: (options === null || options === void 0 ? void 0 : options.messageId) || (0, generics_1.generateMessageID)(),
659
+ id: (options === null || options === void 0 ? void 0 : options.messageId) || (0, generics_1.generateMessageIDV2)(),
551
660
  },
552
661
  message: message,
553
662
  messageTimestamp: timestamp,
@@ -562,7 +671,7 @@ const generateWAMessage = async (jid, content, options) => {
562
671
  var _a;
563
672
  // ensure msg ID is with every log
564
673
  options.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) === null || _a === void 0 ? void 0 : _a.child({ msgId: options.messageId });
565
- return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsLetter)(jid), ...options }), options);
674
+ return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsletter)(jid), ...options }), options);
566
675
  };
567
676
  exports.generateWAMessage = generateWAMessage;
568
677
  /** Get the key to access the true type of content */
@@ -599,7 +708,24 @@ const normalizeMessageContent = (content) => {
599
708
  || (message === null || message === void 0 ? void 0 : message.documentWithCaptionMessage)
600
709
  || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2)
601
710
  || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension)
602
- || (message === null || message === void 0 ? void 0 : message.editedMessage));
711
+ || (message === null || message === void 0 ? void 0 : message.editedMessage)
712
+ || (message === null || message === void 0 ? void 0 : message.groupMentionedMessage)
713
+ || (message === null || message === void 0 ? void 0 : message.botInvokeMessage)
714
+ || (message === null || message === void 0 ? void 0 : message.lottieStickerMessage)
715
+ || (message === null || message === void 0 ? void 0 : message.eventCoverImage)
716
+ || (message === null || message === void 0 ? void 0 : message.statusMentionMessage)
717
+ || (message === null || message === void 0 ? void 0 : message.pollCreationOptionImageMessage)
718
+ || (message === null || message === void 0 ? void 0 : message.associatedChildMessage)
719
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMentionMessage)
720
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV4)
721
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV5)
722
+ || (message === null || message === void 0 ? void 0 : message.statusAddYours)
723
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMessage)
724
+ || (message === null || message === void 0 ? void 0 : message.limitSharingMessage)
725
+ || (message === null || message === void 0 ? void 0 : message.botTaskMessage)
726
+ || (message === null || message === void 0 ? void 0 : message.questionMessage)
727
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMessageV2)
728
+ || (message === null || message === void 0 ? void 0 : message.botForwardedMessage));
603
729
  }
604
730
  };
605
731
  exports.normalizeMessageContent = normalizeMessageContent;
@@ -649,7 +775,11 @@ exports.extractMessageContent = extractMessageContent;
649
775
  /**
650
776
  * Returns the device predicted by message ID
651
777
  */
652
- const getDevice = (id) => /^3A.{18}$/.test(id) ? 'ios' : /^3E.{20}$/.test(id) ? 'web' : /^(.{21}|.{32})$/.test(id) ? 'android' : /^.{18}$/.test(id) ? 'desktop' : 'unknown';
778
+ const getDevice = (id) => /^3A.{18}$/.test(id) ? 'ios' :
779
+ /^3E.{20}$/.test(id) ? 'web' :
780
+ /^(.{21}|.{32})$/.test(id) ? 'android' :
781
+ /^(3F|.{18}$)/.test(id) ? 'desktop' :
782
+ 'unknown';
653
783
  exports.getDevice = getDevice;
654
784
  /** Upserts a receipt in the message */
655
785
  const updateMessageWithReceipt = (msg, receipt) => {
@@ -668,9 +798,8 @@ const updateMessageWithReaction = (msg, reaction) => {
668
798
  const authorID = (0, generics_1.getKeyAuthor)(reaction.key);
669
799
  const reactions = (msg.reactions || [])
670
800
  .filter(r => (0, generics_1.getKeyAuthor)(r.key) !== authorID);
671
- if (reaction.text) {
672
- reactions.push(reaction);
673
- }
801
+ reaction.text = reaction.text || '';
802
+ reactions.push(reaction);
674
803
  msg.reactions = reactions;
675
804
  };
676
805
  exports.updateMessageWithReaction = updateMessageWithReaction;
@@ -723,7 +852,6 @@ function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
723
852
  }
724
853
  return Object.values(voteHashMap);
725
854
  }
726
- exports.getAggregateVotesInPollMessage = getAggregateVotesInPollMessage;
727
855
  /** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
728
856
  const aggregateMessageKeysNotFromMe = (keys) => {
729
857
  const keyMap = {};
@@ -814,3 +942,12 @@ const assertMediaContent = (content) => {
814
942
  return mediaContent;
815
943
  };
816
944
  exports.assertMediaContent = assertMediaContent;
945
+
946
+ const getSenderLid = (message) => {
947
+ const sender = message.key.participant || message.key.remoteJid;
948
+ const user = (0, WABinary_1.jidDecode)(sender)?.user || '';
949
+ const lid = (0, WABinary_1.jidEncode)(user, 'lid');
950
+ console.log('sender lid:', lid);
951
+ return { jid: sender, lid };
952
+ };
953
+ exports.getSenderLid = getSenderLid;