supunmd-bail 2.1.1 → 2.1.3

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 (216) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +428 -0
  3. package/WAProto/index.js +130529 -45236
  4. package/engine-requirements.js +1 -1
  5. package/lib/Defaults/baileys-version.json +1 -1
  6. package/lib/Defaults/index.d.ts +9 -18
  7. package/lib/Defaults/index.js +136 -104
  8. package/lib/Defaults/phonenumber-mcc.json +223 -0
  9. package/lib/Signal/Group/ciphertext-message.d.ts +0 -1
  10. package/lib/Signal/Group/ciphertext-message.js +5 -2
  11. package/lib/Signal/Group/group-session-builder.d.ts +3 -4
  12. package/lib/Signal/Group/group-session-builder.js +41 -7
  13. package/lib/Signal/Group/group_cipher.d.ts +4 -4
  14. package/lib/Signal/Group/group_cipher.js +51 -37
  15. package/lib/Signal/Group/index.d.ts +11 -12
  16. package/lib/Signal/Group/index.js +57 -12
  17. package/lib/Signal/Group/keyhelper.d.ts +1 -2
  18. package/lib/Signal/Group/keyhelper.js +44 -7
  19. package/lib/Signal/Group/queue-job.d.ts +0 -1
  20. package/lib/Signal/Group/queue-job.js +5 -2
  21. package/lib/Signal/Group/sender-chain-key.d.ts +2 -3
  22. package/lib/Signal/Group/sender-chain-key.js +15 -7
  23. package/lib/Signal/Group/sender-key-distribution-message.d.ts +1 -2
  24. package/lib/Signal/Group/sender-key-distribution-message.js +11 -8
  25. package/lib/Signal/Group/sender-key-message.d.ts +1 -2
  26. package/lib/Signal/Group/sender-key-message.js +12 -9
  27. package/lib/Signal/Group/sender-key-name.d.ts +0 -1
  28. package/lib/Signal/Group/sender-key-name.js +5 -2
  29. package/lib/Signal/Group/sender-key-record.d.ts +2 -3
  30. package/lib/Signal/Group/sender-key-record.js +21 -9
  31. package/lib/Signal/Group/sender-key-state.d.ts +6 -7
  32. package/lib/Signal/Group/sender-key-state.js +42 -27
  33. package/lib/Signal/Group/sender-message-key.d.ts +0 -1
  34. package/lib/Signal/Group/sender-message-key.js +7 -4
  35. package/lib/Signal/libsignal.d.ts +3 -5
  36. package/lib/Signal/libsignal.js +90 -258
  37. package/lib/Socket/Client/{types.d.ts → abstract-socket-client.d.ts} +3 -2
  38. package/lib/Socket/Client/abstract-socket-client.js +13 -0
  39. package/lib/Socket/Client/index.d.ts +3 -3
  40. package/lib/Socket/Client/index.js +19 -3
  41. package/lib/Socket/Client/mobile-socket-client.d.ts +13 -0
  42. package/lib/Socket/Client/mobile-socket-client.js +65 -0
  43. package/lib/Socket/Client/{websocket.d.ts → web-socket-client.d.ts} +1 -2
  44. package/lib/Socket/Client/web-socket-client.js +62 -0
  45. package/lib/Socket/business.d.ts +108 -125
  46. package/lib/Socket/business.js +43 -159
  47. package/lib/Socket/chats.d.ts +239 -70
  48. package/lib/Socket/chats.js +384 -363
  49. package/lib/Socket/dugong.d.ts +254 -0
  50. package/lib/Socket/dugong.js +484 -0
  51. package/lib/Socket/groups.d.ts +56 -78
  52. package/lib/Socket/groups.js +96 -106
  53. package/lib/Socket/index.d.ts +115 -173
  54. package/lib/Socket/index.js +10 -17
  55. package/lib/Socket/messages-recv.d.ts +79 -91
  56. package/lib/Socket/messages-recv.js +521 -639
  57. package/lib/Socket/messages-send.d.ts +91 -111
  58. package/lib/Socket/messages-send.js +438 -599
  59. package/lib/Socket/newsletter.d.ts +84 -97
  60. package/lib/Socket/newsletter.js +1 -181
  61. package/lib/Socket/registration.d.ts +267 -0
  62. package/lib/Socket/registration.js +166 -0
  63. package/lib/Socket/socket.d.ts +18 -26
  64. package/lib/Socket/socket.js +230 -448
  65. package/lib/Socket/usync.d.ts +16 -17
  66. package/lib/Socket/usync.js +26 -19
  67. package/lib/Store/index.d.ts +3 -0
  68. package/lib/Store/index.js +10 -0
  69. package/lib/Store/make-cache-manager-store.d.ts +13 -0
  70. package/lib/Store/make-cache-manager-store.js +83 -0
  71. package/lib/Store/make-in-memory-store.d.ts +118 -0
  72. package/lib/Store/make-in-memory-store.js +427 -0
  73. package/lib/Store/make-ordered-dictionary.d.ts +13 -0
  74. package/lib/Store/make-ordered-dictionary.js +81 -0
  75. package/lib/Store/object-repository.d.ts +10 -0
  76. package/lib/Store/object-repository.js +27 -0
  77. package/lib/Types/Auth.d.ts +12 -13
  78. package/lib/Types/Auth.js +2 -2
  79. package/lib/Types/Call.d.ts +1 -2
  80. package/lib/Types/Call.js +2 -2
  81. package/lib/Types/Chat.d.ts +13 -34
  82. package/lib/Types/Chat.js +4 -8
  83. package/lib/Types/Contact.d.ts +1 -6
  84. package/lib/Types/Contact.js +2 -2
  85. package/lib/Types/Events.d.ts +15 -60
  86. package/lib/Types/Events.js +2 -2
  87. package/lib/Types/GroupMetadata.d.ts +5 -17
  88. package/lib/Types/GroupMetadata.js +2 -2
  89. package/lib/Types/Label.d.ts +0 -12
  90. package/lib/Types/Label.js +5 -3
  91. package/lib/Types/LabelAssociation.d.ts +0 -1
  92. package/lib/Types/LabelAssociation.js +5 -3
  93. package/lib/Types/Message.d.ts +54 -84
  94. package/lib/Types/Message.js +9 -11
  95. package/lib/Types/Newsletter.d.ts +98 -130
  96. package/lib/Types/Newsletter.js +38 -31
  97. package/lib/Types/Product.d.ts +1 -2
  98. package/lib/Types/Product.js +2 -2
  99. package/lib/Types/Signal.d.ts +1 -20
  100. package/lib/Types/Signal.js +2 -2
  101. package/lib/Types/Socket.d.ts +25 -47
  102. package/lib/Types/Socket.js +2 -3
  103. package/lib/Types/State.d.ts +2 -14
  104. package/lib/Types/State.js +2 -13
  105. package/lib/Types/USync.d.ts +2 -3
  106. package/lib/Types/USync.js +2 -2
  107. package/lib/Types/index.d.ts +14 -22
  108. package/lib/Types/index.js +31 -15
  109. package/lib/Utils/auth-utils.d.ts +6 -7
  110. package/lib/Utils/auth-utils.js +148 -199
  111. package/lib/Utils/baileys-event-stream.d.ts +1 -2
  112. package/lib/Utils/baileys-event-stream.js +22 -15
  113. package/lib/Utils/business.d.ts +2 -3
  114. package/lib/Utils/business.js +69 -66
  115. package/lib/Utils/chat-utils.d.ts +22 -21
  116. package/lib/Utils/chat-utils.js +226 -260
  117. package/lib/Utils/crypto.d.ts +19 -19
  118. package/lib/Utils/crypto.js +86 -77
  119. package/lib/Utils/decode-wa-message.d.ts +8 -37
  120. package/lib/Utils/decode-wa-message.js +83 -164
  121. package/lib/Utils/event-buffer.d.ts +8 -7
  122. package/lib/Utils/event-buffer.js +76 -110
  123. package/lib/Utils/generics.d.ts +29 -27
  124. package/lib/Utils/generics.js +210 -168
  125. package/lib/Utils/history.d.ts +8 -12
  126. package/lib/Utils/history.js +46 -34
  127. package/lib/Utils/index.d.ts +17 -20
  128. package/lib/Utils/index.js +33 -20
  129. package/lib/Utils/link-preview.d.ts +5 -5
  130. package/lib/Utils/link-preview.js +22 -14
  131. package/lib/Utils/logger.d.ts +3 -11
  132. package/lib/Utils/logger.js +7 -3
  133. package/lib/Utils/lt-hash.d.ts +8 -9
  134. package/lib/Utils/lt-hash.js +28 -25
  135. package/lib/Utils/make-mutex.d.ts +2 -3
  136. package/lib/Utils/make-mutex.js +10 -7
  137. package/lib/Utils/messages-media.d.ts +44 -42
  138. package/lib/Utils/messages-media.js +475 -319
  139. package/lib/Utils/messages.d.ts +18 -17
  140. package/lib/Utils/messages.js +259 -383
  141. package/lib/Utils/noise-handler.d.ts +15 -14
  142. package/lib/Utils/noise-handler.js +38 -30
  143. package/lib/Utils/process-message.d.ts +13 -14
  144. package/lib/Utils/process-message.js +147 -239
  145. package/lib/Utils/signal.d.ts +5 -7
  146. package/lib/Utils/signal.js +72 -78
  147. package/lib/Utils/use-multi-file-auth-state.d.ts +2 -2
  148. package/lib/Utils/use-multi-file-auth-state.js +27 -29
  149. package/lib/Utils/validate-connection.d.ts +7 -7
  150. package/lib/Utils/validate-connection.js +106 -72
  151. package/lib/WABinary/constants.d.ts +27 -25
  152. package/lib/WABinary/constants.js +20 -1281
  153. package/lib/WABinary/decode.d.ts +5 -5
  154. package/lib/WABinary/decode.js +42 -28
  155. package/lib/WABinary/encode.d.ts +3 -3
  156. package/lib/WABinary/encode.js +154 -105
  157. package/lib/WABinary/generic-utils.d.ts +7 -5
  158. package/lib/WABinary/generic-utils.js +63 -56
  159. package/lib/WABinary/index.d.ts +5 -6
  160. package/lib/WABinary/index.js +21 -6
  161. package/lib/WABinary/jid-utils.d.ts +8 -25
  162. package/lib/WABinary/jid-utils.js +40 -74
  163. package/lib/WABinary/types.d.ts +1 -2
  164. package/lib/WABinary/types.js +2 -2
  165. package/lib/WAM/BinaryInfo.d.ts +11 -3
  166. package/lib/WAM/BinaryInfo.js +5 -2
  167. package/lib/WAM/constants.d.ts +3 -5
  168. package/lib/WAM/constants.js +11958 -19461
  169. package/lib/WAM/encode.d.ts +3 -3
  170. package/lib/WAM/encode.js +22 -17
  171. package/lib/WAM/index.d.ts +3 -4
  172. package/lib/WAM/index.js +19 -4
  173. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +3 -4
  174. package/lib/WAUSync/Protocols/USyncContactProtocol.js +11 -8
  175. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +2 -3
  176. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +14 -11
  177. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +2 -3
  178. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +12 -9
  179. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +2 -3
  180. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +13 -9
  181. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +3 -4
  182. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +22 -20
  183. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +3 -5
  184. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +8 -13
  185. package/lib/WAUSync/Protocols/index.d.ts +4 -5
  186. package/lib/WAUSync/Protocols/index.js +20 -5
  187. package/lib/WAUSync/USyncQuery.d.ts +4 -5
  188. package/lib/WAUSync/USyncQuery.js +35 -40
  189. package/lib/WAUSync/USyncUser.d.ts +5 -6
  190. package/lib/WAUSync/USyncUser.js +5 -2
  191. package/lib/WAUSync/index.d.ts +3 -4
  192. package/lib/WAUSync/index.js +19 -4
  193. package/lib/index.d.ts +9 -19
  194. package/lib/index.js +1 -36
  195. package/package.json +109 -99
  196. package/WAProto/GenerateStatics.sh +0 -3
  197. package/WAProto/WAProto.proto +0 -5519
  198. package/WAProto/fix-imports.js +0 -29
  199. package/WAProto/index.d.ts +0 -11969
  200. package/lib/Signal/lid-mapping.d.ts +0 -23
  201. package/lib/Signal/lid-mapping.js +0 -171
  202. package/lib/Socket/Client/types.js +0 -11
  203. package/lib/Socket/Client/websocket.js +0 -50
  204. package/lib/Socket/communities.d.ts +0 -244
  205. package/lib/Socket/communities.js +0 -431
  206. package/lib/Socket/mex.d.ts +0 -3
  207. package/lib/Socket/mex.js +0 -42
  208. package/lib/Types/Bussines.d.ts +0 -25
  209. package/lib/Types/Bussines.js +0 -2
  210. package/lib/Utils/browser-utils.d.ts +0 -4
  211. package/lib/Utils/browser-utils.js +0 -28
  212. package/lib/Utils/message-retry-manager.d.ts +0 -82
  213. package/lib/Utils/message-retry-manager.js +0 -149
  214. package/lib/Utils/pre-key-manager.d.ts +0 -28
  215. package/lib/Utils/pre-key-manager.js +0 -106
  216. /package/lib/{supun → supunmd} +0 -0
@@ -1,218 +1,64 @@
1
- import NodeCache from '@cacheable/node-cache';
2
- import { Boom } from '@hapi/boom';
3
- import { randomBytes } from 'crypto';
4
- import Long from 'long';
5
- import { proto } from '../../WAProto/index.js';
6
- import { DEFAULT_CACHE_TTLS, KEY_BUNDLE_TYPE, MIN_PREKEY_COUNT } from '../Defaults/index.js';
7
- import { WAMessageStatus, WAMessageStubType } from '../Types/index.js';
8
- import { aesDecryptCTR, aesEncryptGCM, cleanMessage, Curve, decodeMediaRetryNode, decodeMessageNode, decryptMessageNode, delay, derivePairingCodeKey, encodeBigEndian, encodeSignedDeviceIdentity, extractAddressingContext, getCallStatusFromNode, getHistoryMsg, getNextPreKeys, getStatusFromReceiptType, hkdf, MISSING_KEYS_ERROR_TEXT, NACK_REASONS, unixTimestampSeconds, xmppPreKey, xmppSignedPreKey } from '../Utils/index.js';
9
- import { makeMutex } from '../Utils/make-mutex.js';
10
- import { areJidsSameUser, binaryNodeToString, getAllBinaryNodeChildren, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildren, getBinaryNodeChildString, isJidGroup, isJidStatusBroadcast, isLidUser, isPnUser, jidDecode, jidNormalizedUser, S_WHATSAPP_NET } from '../WABinary/index.js';
11
- import { extractGroupMetadata } from './groups.js';
12
- import { makeMessagesSocket } from './messages-send.js';
13
- export const makeMessagesRecvSocket = (config) => {
14
- const { logger, retryRequestDelayMs, maxMsgRetryCount, getMessage, shouldIgnoreJid, enableAutoSessionRecreation } = config;
15
- const sock = makeMessagesSocket(config);
16
- const { ev, authState, ws, processingMutex, signalRepository, query, upsertMessage, resyncAppState, onUnexpectedError, assertSessions, sendNode, relayMessage, sendReceipt, uploadPreKeys, sendPeerDataOperationMessage, messageRetryManager } = sock;
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.makeMessagesRecvSocket = void 0;
7
+ const boom_1 = require("@hapi/boom");
8
+ const crypto_1 = require("crypto");
9
+ const node_cache_1 = __importDefault(require("@cacheable/node-cache"));
10
+ const WAProto_1 = require("../../WAProto");
11
+ const Defaults_1 = require("../Defaults");
12
+ const Types_1 = require("../Types");
13
+ const Utils_1 = require("../Utils");
14
+ const make_mutex_1 = require("../Utils/make-mutex");
15
+ const WABinary_1 = require("../WABinary");
16
+ const groups_1 = require("./groups");
17
+ const messages_send_1 = require("./messages-send");
18
+ const makeMessagesRecvSocket = (config) => {
19
+ const {
20
+ logger,
21
+ retryRequestDelayMs,
22
+ maxMsgRetryCount,
23
+ getMessage,
24
+ shouldIgnoreJid
25
+ } = config;
26
+ const sock = (0, messages_send_1.makeMessagesSocket)(config);
27
+ const {
28
+ ev,
29
+ authState,
30
+ ws,
31
+ processingMutex,
32
+ signalRepository,
33
+ query,
34
+ upsertMessage,
35
+ resyncAppState,
36
+ groupMetadata,
37
+ onUnexpectedError,
38
+ assertSessions,
39
+ sendNode,
40
+ relayMessage,
41
+ sendReceipt,
42
+ uploadPreKeys,
43
+ createParticipantNodes,
44
+ getUSyncDevices,
45
+ sendPeerDataOperationMessage
46
+ } = sock;
17
47
  /** this mutex ensures that each retryRequest will wait for the previous one to finish */
18
- const retryMutex = makeMutex();
19
- const msgRetryCache = config.msgRetryCounterCache ||
20
- new NodeCache({
21
- stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
22
- useClones: false
23
- });
24
- const callOfferCache = config.callOfferCache ||
25
- new NodeCache({
26
- stdTTL: DEFAULT_CACHE_TTLS.CALL_OFFER, // 5 mins
27
- useClones: false
28
- });
29
- const placeholderResendCache = config.placeholderResendCache ||
30
- new NodeCache({
31
- stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
32
- useClones: false
33
- });
48
+ const retryMutex = (0, make_mutex_1.makeMutex)();
49
+ const msgRetryCache = config.msgRetryCounterCache || new node_cache_1.default({
50
+ stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
51
+ useClones: false
52
+ });
53
+ const callOfferCache = config.callOfferCache || new node_cache_1.default({
54
+ stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.CALL_OFFER, // 5 mins
55
+ useClones: false
56
+ });
57
+ const placeholderResendCache = config.placeholderResendCache || new node_cache_1.default({
58
+ stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
59
+ useClones: false
60
+ });
34
61
  let sendActiveReceipts = false;
35
- const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
36
- if (!authState.creds.me?.id) {
37
- throw new Boom('Not authenticated');
38
- }
39
- const pdoMessage = {
40
- historySyncOnDemandRequest: {
41
- chatJid: oldestMsgKey.remoteJid,
42
- oldestMsgFromMe: oldestMsgKey.fromMe,
43
- oldestMsgId: oldestMsgKey.id,
44
- oldestMsgTimestampMs: oldestMsgTimestamp,
45
- onDemandMsgCount: count
46
- },
47
- peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
48
- };
49
- return sendPeerDataOperationMessage(pdoMessage);
50
- };
51
- const requestPlaceholderResend = async (messageKey) => {
52
- if (!authState.creds.me?.id) {
53
- throw new Boom('Not authenticated');
54
- }
55
- if (placeholderResendCache.get(messageKey?.id)) {
56
- logger.debug({ messageKey }, 'already requested resend');
57
- return;
58
- }
59
- else {
60
- placeholderResendCache.set(messageKey?.id, true);
61
- }
62
- await delay(5000);
63
- if (!placeholderResendCache.get(messageKey?.id)) {
64
- logger.debug({ messageKey }, 'message received while resend requested');
65
- return 'RESOLVED';
66
- }
67
- const pdoMessage = {
68
- placeholderMessageResendRequest: [
69
- {
70
- messageKey
71
- }
72
- ],
73
- peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
74
- };
75
- setTimeout(() => {
76
- if (placeholderResendCache.get(messageKey?.id)) {
77
- logger.debug({ messageKey }, 'PDO message without response after 15 seconds. Phone possibly offline');
78
- placeholderResendCache.del(messageKey?.id);
79
- }
80
- }, 15000);
81
- return sendPeerDataOperationMessage(pdoMessage);
82
- };
83
- // Handles mex newsletter notifications
84
- const handleMexNewsletterNotification = async (node) => {
85
- const mexNode = getBinaryNodeChild(node, 'mex');
86
- if (!mexNode?.content) {
87
- logger.warn({ node }, 'Invalid mex newsletter notification');
88
- return;
89
- }
90
- let data;
91
- try {
92
- data = JSON.parse(mexNode.content.toString());
93
- }
94
- catch (error) {
95
- logger.error({ err: error, node }, 'Failed to parse mex newsletter notification');
96
- return;
97
- }
98
- const operation = data?.operation;
99
- const updates = data?.updates;
100
- if (!updates || !operation) {
101
- logger.warn({ data }, 'Invalid mex newsletter notification content');
102
- return;
103
- }
104
- logger.info({ operation, updates }, 'got mex newsletter notification');
105
- switch (operation) {
106
- case 'NotificationNewsletterUpdate':
107
- for (const update of updates) {
108
- if (update.jid && update.settings && Object.keys(update.settings).length > 0) {
109
- ev.emit('newsletter-settings.update', {
110
- id: update.jid,
111
- update: update.settings
112
- });
113
- }
114
- }
115
- break;
116
- case 'NotificationNewsletterAdminPromote':
117
- for (const update of updates) {
118
- if (update.jid && update.user) {
119
- ev.emit('newsletter-participants.update', {
120
- id: update.jid,
121
- author: node.attrs.from,
122
- user: update.user,
123
- new_role: 'ADMIN',
124
- action: 'promote'
125
- });
126
- }
127
- }
128
- break;
129
- default:
130
- logger.info({ operation, data }, 'Unhandled mex newsletter notification');
131
- break;
132
- }
133
- };
134
- // Handles newsletter notifications
135
- const handleNewsletterNotification = async (node) => {
136
- const from = node.attrs.from;
137
- const child = getAllBinaryNodeChildren(node)[0];
138
- const author = node.attrs.participant;
139
- logger.info({ from, child }, 'got newsletter notification');
140
- switch (child.tag) {
141
- case 'reaction':
142
- const reactionUpdate = {
143
- id: from,
144
- server_id: child.attrs.message_id,
145
- reaction: {
146
- code: getBinaryNodeChildString(child, 'reaction'),
147
- count: 1
148
- }
149
- };
150
- ev.emit('newsletter.reaction', reactionUpdate);
151
- break;
152
- case 'view':
153
- const viewUpdate = {
154
- id: from,
155
- server_id: child.attrs.message_id,
156
- count: parseInt(child.content?.toString() || '0', 10)
157
- };
158
- ev.emit('newsletter.view', viewUpdate);
159
- break;
160
- case 'participant':
161
- const participantUpdate = {
162
- id: from,
163
- author,
164
- user: child.attrs.jid,
165
- action: child.attrs.action,
166
- new_role: child.attrs.role
167
- };
168
- ev.emit('newsletter-participants.update', participantUpdate);
169
- break;
170
- case 'update':
171
- const settingsNode = getBinaryNodeChild(child, 'settings');
172
- if (settingsNode) {
173
- const update = {};
174
- const nameNode = getBinaryNodeChild(settingsNode, 'name');
175
- if (nameNode?.content)
176
- update.name = nameNode.content.toString();
177
- const descriptionNode = getBinaryNodeChild(settingsNode, 'description');
178
- if (descriptionNode?.content)
179
- update.description = descriptionNode.content.toString();
180
- ev.emit('newsletter-settings.update', {
181
- id: from,
182
- update
183
- });
184
- }
185
- break;
186
- case 'message':
187
- const plaintextNode = getBinaryNodeChild(child, 'plaintext');
188
- if (plaintextNode?.content) {
189
- try {
190
- const contentBuf = typeof plaintextNode.content === 'string'
191
- ? Buffer.from(plaintextNode.content, 'binary')
192
- : Buffer.from(plaintextNode.content);
193
- const messageProto = proto.Message.decode(contentBuf).toJSON();
194
- const fullMessage = proto.WebMessageInfo.fromObject({
195
- key: {
196
- remoteJid: from,
197
- id: child.attrs.message_id || child.attrs.server_id,
198
- fromMe: false // TODO: is this really true though
199
- },
200
- message: messageProto,
201
- messageTimestamp: +child.attrs.t
202
- }).toJSON();
203
- await upsertMessage(fullMessage, 'append');
204
- logger.info('Processed plaintext newsletter message');
205
- }
206
- catch (error) {
207
- logger.error({ error }, 'Failed to decode plaintext newsletter message');
208
- }
209
- }
210
- break;
211
- default:
212
- logger.warn({ node }, 'Unknown newsletter notification');
213
- break;
214
- }
215
- };
216
62
  const sendMessageAck = async ({ tag, attrs, content }, errorCode) => {
217
63
  const stanza = {
218
64
  tag: 'ack',
@@ -221,7 +67,7 @@ export const makeMessagesRecvSocket = (config) => {
221
67
  to: attrs.from,
222
68
  class: tag
223
69
  }
224
- };
70
+ }
225
71
  if (!!errorCode) {
226
72
  stanza.attrs.error = errorCode.toString();
227
73
  }
@@ -231,113 +77,143 @@ export const makeMessagesRecvSocket = (config) => {
231
77
  if (!!attrs.recipient) {
232
78
  stanza.attrs.recipient = attrs.recipient;
233
79
  }
234
- if (!!attrs.type &&
235
- (tag !== 'message' || getBinaryNodeChild({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
80
+ if (!!attrs.type && (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
236
81
  stanza.attrs.type = attrs.type;
237
82
  }
238
- if (tag === 'message' && getBinaryNodeChild({ tag, attrs, content }, 'unavailable')) {
83
+ if (tag === 'message' && (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable')) {
239
84
  stanza.attrs.from = authState.creds.me.id;
240
85
  }
241
- logger.debug({ recv: { tag, attrs }, sent: stanza.attrs }, 'sent ack');
86
+ logger.debug({
87
+ recv: {
88
+ tag,
89
+ attrs
90
+ },
91
+ sent: stanza.attrs }, 'sent ack');
242
92
  await sendNode(stanza);
243
93
  };
94
+ const offerCall = async (toJid, isVideo = false) => {
95
+ const callId = (0, crypto_1.randomBytes)(16).toString('hex').toUpperCase().substring(0, 64);
96
+ const offerContent = [];
97
+ offerContent.push({
98
+ tag: 'audio',
99
+ attrs: {
100
+ enc: 'opus',
101
+ rate: '16000'
102
+ }, content: undefined
103
+ });
104
+ offerContent.push({
105
+ tag: 'audio',
106
+ attrs: {
107
+ enc: 'opus',
108
+ rate: '8000'
109
+ }, content: undefined
110
+ });
111
+ if (isVideo) {
112
+ offerContent.push({
113
+ tag: 'video',
114
+ attrs: {
115
+ orientation: '0',
116
+ 'screen_width': '1920',
117
+ 'screen_height': '1080',
118
+ 'device_orientation': '0',
119
+ enc: 'vp8',
120
+ dec: 'vp8',
121
+ }
122
+ });
123
+ }
124
+ offerContent.push({
125
+ tag: 'net',
126
+ attrs: {
127
+ medium: '3'
128
+ }, content: undefined
129
+ });
130
+ offerContent.push({
131
+ tag: 'capability',
132
+ attrs: {
133
+ ver: '1'
134
+ }, content: new Uint8Array([1, 4, 255, 131, 207, 4]) });
135
+ offerContent.push({
136
+ tag: 'encopt',
137
+ attrs: {
138
+ keygen: '2'
139
+ }, content: undefined
140
+ })
141
+ const encKey = (0, crypto_1.randomBytes)(32);
142
+ const devices = (await getUSyncDevices([toJid], true, false)).map(({ user, device }) => (0, WABinary_1.jidEncode)(user, 's.whatsapp.net', device));
143
+ await assertSessions(devices, true);
144
+ const { nodes: destinations, shouldIncludeDeviceIdentity } = await createParticipantNodes(devices, {
145
+ call: {
146
+ callKey: encKey
147
+ }
148
+ });
149
+ offerContent.push({ tag: 'destination', attrs: {}, content: destinations });
150
+ if (shouldIncludeDeviceIdentity) {
151
+ offerContent.push({
152
+ tag: 'device-identity',
153
+ attrs: {},
154
+ content: (0, Utils_1.encodeSignedDeviceIdentity)(authState.creds.account, true)
155
+ });
156
+ }
157
+ const stanza = ({
158
+ tag: 'call',
159
+ attrs: {
160
+ to: toJid,
161
+ },
162
+ content: [{
163
+ tag: 'offer',
164
+ attrs: {
165
+ 'call-id': callId,
166
+ 'call-creator': authState.creds.me.id,
167
+ },
168
+ content: offerContent,
169
+ }],
170
+ });
171
+ await query(stanza);
172
+ return {
173
+ callId,
174
+ toJid,
175
+ isVideo,
176
+ };
177
+ };
244
178
  const rejectCall = async (callId, callFrom) => {
245
- const stanza = {
179
+ const stanza = ({
246
180
  tag: 'call',
247
181
  attrs: {
248
182
  from: authState.creds.me.id,
249
- to: callFrom
183
+ to: callFrom,
250
184
  },
251
- content: [
252
- {
185
+ content: [{
253
186
  tag: 'reject',
254
187
  attrs: {
255
188
  'call-id': callId,
256
189
  'call-creator': callFrom,
257
- count: '0'
190
+ count: '0',
258
191
  },
259
- content: undefined
260
- }
261
- ]
262
- };
192
+ content: undefined,
193
+ }],
194
+ });
263
195
  await query(stanza);
264
196
  };
265
197
  const sendRetryRequest = async (node, forceIncludeKeys = false) => {
266
- const { fullMessage } = decodeMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '');
198
+ const { fullMessage } = (0, Utils_1.decodeMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '');
267
199
  const { key: msgKey } = fullMessage;
268
200
  const msgId = msgKey.id;
269
- if (messageRetryManager) {
270
- // Check if we've exceeded max retries using the new system
271
- if (messageRetryManager.hasExceededMaxRetries(msgId)) {
272
- logger.debug({ msgId }, 'reached retry limit with new retry manager, clearing');
273
- messageRetryManager.markRetryFailed(msgId);
274
- return;
275
- }
276
- // Increment retry count using new system
277
- const retryCount = messageRetryManager.incrementRetryCount(msgId);
278
- // Use the new retry count for the rest of the logic
279
- const key = `${msgId}:${msgKey?.participant}`;
280
- msgRetryCache.set(key, retryCount);
281
- }
282
- else {
283
- // Fallback to old system
284
- const key = `${msgId}:${msgKey?.participant}`;
285
- let retryCount = (await msgRetryCache.get(key)) || 0;
286
- if (retryCount >= maxMsgRetryCount) {
287
- logger.debug({ retryCount, msgId }, 'reached retry limit, clearing');
288
- msgRetryCache.del(key);
289
- return;
290
- }
291
- retryCount += 1;
292
- await msgRetryCache.set(key, retryCount);
201
+ const key = `${msgId}:${msgKey === null || msgKey === void 0 ? void 0 : msgKey.participant}`;
202
+ let retryCount = msgRetryCache.get(key) || 0;
203
+ if (retryCount >= maxMsgRetryCount) {
204
+ logger.debug({ retryCount, msgId }, 'reached retry limit, clearing');
205
+ msgRetryCache.del(key);
206
+ return;
293
207
  }
294
- const key = `${msgId}:${msgKey?.participant}`;
295
- const retryCount = (await msgRetryCache.get(key)) || 1;
208
+ retryCount += 1;
209
+ msgRetryCache.set(key, retryCount);
296
210
  const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds;
297
- const fromJid = node.attrs.from;
298
- // Check if we should recreate the session
299
- let shouldRecreateSession = false;
300
- let recreateReason = '';
301
- if (enableAutoSessionRecreation && messageRetryManager) {
302
- try {
303
- // Check if we have a session with this JID
304
- const sessionId = signalRepository.jidToSignalProtocolAddress(fromJid);
305
- const hasSession = await signalRepository.validateSession(fromJid);
306
- const result = messageRetryManager.shouldRecreateSession(fromJid, retryCount, hasSession.exists);
307
- shouldRecreateSession = result.recreate;
308
- recreateReason = result.reason;
309
- if (shouldRecreateSession) {
310
- logger.debug({ fromJid, retryCount, reason: recreateReason }, 'recreating session for retry');
311
- // Delete existing session to force recreation
312
- await authState.keys.set({ session: { [sessionId]: null } });
313
- forceIncludeKeys = true;
314
- }
315
- }
316
- catch (error) {
317
- logger.warn({ error, fromJid }, 'failed to check session recreation');
318
- }
211
+ if (retryCount === 1) {
212
+ //request a resend via phone
213
+ const msgId = await requestPlaceholderResend(msgKey);
214
+ logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId}`);
319
215
  }
320
- if (retryCount <= 2) {
321
- // Use new retry manager for phone requests if available
322
- if (messageRetryManager) {
323
- // Schedule phone request with delay (like whatsmeow)
324
- messageRetryManager.schedulePhoneRequest(msgId, async () => {
325
- try {
326
- const requestId = await requestPlaceholderResend(msgKey);
327
- logger.debug(`sendRetryRequest: requested placeholder resend (${requestId}) for message ${msgId} (scheduled)`);
328
- }
329
- catch (error) {
330
- logger.warn({ error, msgId }, 'failed to send scheduled phone request');
331
- }
332
- });
333
- }
334
- else {
335
- // Fallback to immediate request
336
- const msgId = await requestPlaceholderResend(msgKey);
337
- logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId}`);
338
- }
339
- }
340
- const deviceIdentity = encodeSignedDeviceIdentity(account, true);
216
+ const deviceIdentity = (0, Utils_1.encodeSignedDeviceIdentity)(account, true);
341
217
  await authState.keys.transaction(async () => {
342
218
  const receipt = {
343
219
  tag: 'receipt',
@@ -353,15 +229,13 @@ export const makeMessagesRecvSocket = (config) => {
353
229
  count: retryCount.toString(),
354
230
  id: node.attrs.id,
355
231
  t: node.attrs.t,
356
- v: '1',
357
- // ADD ERROR FIELD
358
- error: '0'
232
+ v: '1'
359
233
  }
360
234
  },
361
235
  {
362
236
  tag: 'registration',
363
237
  attrs: {},
364
- content: encodeBigEndian(authState.creds.registrationId)
238
+ content: (0, Utils_1.encodeBigEndian)(authState.creds.registrationId)
365
239
  }
366
240
  ]
367
241
  };
@@ -371,8 +245,8 @@ export const makeMessagesRecvSocket = (config) => {
371
245
  if (node.attrs.participant) {
372
246
  receipt.attrs.participant = node.attrs.participant;
373
247
  }
374
- if (retryCount > 1 || forceIncludeKeys || shouldRecreateSession) {
375
- const { update, preKeys } = await getNextPreKeys(authState, 1);
248
+ if (retryCount > 1 || forceIncludeKeys) {
249
+ const { update, preKeys } = await (0, Utils_1.getNextPreKeys)(authState, 1);
376
250
  const [keyId] = Object.keys(preKeys);
377
251
  const key = preKeys[+keyId];
378
252
  const content = receipt.content;
@@ -380,10 +254,10 @@ export const makeMessagesRecvSocket = (config) => {
380
254
  tag: 'keys',
381
255
  attrs: {},
382
256
  content: [
383
- { tag: 'type', attrs: {}, content: Buffer.from(KEY_BUNDLE_TYPE) },
257
+ { tag: 'type', attrs: {}, content: Buffer.from(Defaults_1.KEY_BUNDLE_TYPE) },
384
258
  { tag: 'identity', attrs: {}, content: identityKey.public },
385
- xmppPreKey(key, +keyId),
386
- xmppSignedPreKey(signedPreKey),
259
+ (0, Utils_1.xmppPreKey)(key, +keyId),
260
+ (0, Utils_1.xmppSignedPreKey)(signedPreKey),
387
261
  { tag: 'device-identity', attrs: {}, content: deviceIdentity }
388
262
  ]
389
263
  });
@@ -391,21 +265,21 @@ export const makeMessagesRecvSocket = (config) => {
391
265
  }
392
266
  await sendNode(receipt);
393
267
  logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt');
394
- }, authState?.creds?.me?.id || 'sendRetryRequest');
268
+ });
395
269
  };
396
270
  const handleEncryptNotification = async (node) => {
397
271
  const from = node.attrs.from;
398
- if (from === S_WHATSAPP_NET) {
399
- const countChild = getBinaryNodeChild(node, 'count');
272
+ if (from === WABinary_1.S_WHATSAPP_NET) {
273
+ const countChild = (0, WABinary_1.getBinaryNodeChild)(node, 'count');
400
274
  const count = +countChild.attrs.value;
401
- const shouldUploadMorePreKeys = count < MIN_PREKEY_COUNT;
275
+ const shouldUploadMorePreKeys = count < Defaults_1.MIN_PREKEY_COUNT;
402
276
  logger.debug({ count, shouldUploadMorePreKeys }, 'recv pre-key count');
403
277
  if (shouldUploadMorePreKeys) {
404
278
  await uploadPreKeys();
405
279
  }
406
280
  }
407
281
  else {
408
- const identityNode = getBinaryNodeChild(node, 'identity');
282
+ const identityNode = (0, WABinary_1.getBinaryNodeChild)(node, 'identity');
409
283
  if (identityNode) {
410
284
  logger.info({ jid: from }, 'identity changed');
411
285
  // not handling right now
@@ -416,46 +290,38 @@ export const makeMessagesRecvSocket = (config) => {
416
290
  }
417
291
  }
418
292
  };
419
- const handleGroupNotification = (fullNode, child, msg) => {
420
- // TODO: Support PN/LID (Here is only LID now)
421
- const actingParticipantLid = fullNode.attrs.participant;
422
- const actingParticipantPn = fullNode.attrs.participant_pn;
423
- const affectedParticipantLid = getBinaryNodeChild(child, 'participant')?.attrs?.jid || actingParticipantLid;
424
- const affectedParticipantPn = getBinaryNodeChild(child, 'participant')?.attrs?.phone_number || actingParticipantPn;
425
- switch (child?.tag) {
293
+ const handleGroupNotification = (participant, child, msg) => {
294
+ var _a, _b, _c, _d;
295
+ const participantJid = ((_b = (_a = (0, WABinary_1.getBinaryNodeChild)(child, 'participant')) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.jid) || participant;
296
+ switch (child === null || child === void 0 ? void 0 : child.tag) {
426
297
  case 'create':
427
- const metadata = extractGroupMetadata(child);
428
- msg.messageStubType = WAMessageStubType.GROUP_CREATE;
298
+ const metadata = (0, groups_1.extractGroupMetadata)(child);
299
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_CREATE;
429
300
  msg.messageStubParameters = [metadata.subject];
430
- msg.key = { participant: metadata.owner, participantAlt: metadata.ownerPn };
431
- ev.emit('chats.upsert', [
432
- {
301
+ msg.key = { participant: metadata.owner };
302
+ ev.emit('chats.upsert', [{
433
303
  id: metadata.id,
434
304
  name: metadata.subject,
435
- conversationTimestamp: metadata.creation
436
- }
437
- ]);
438
- ev.emit('groups.upsert', [
439
- {
305
+ conversationTimestamp: metadata.creation,
306
+ }]);
307
+ ev.emit('groups.upsert', [{
440
308
  ...metadata,
441
- author: actingParticipantLid,
442
- authorPn: actingParticipantPn
443
- }
444
- ]);
309
+ author: participant
310
+ }]);
445
311
  break;
446
312
  case 'ephemeral':
447
313
  case 'not_ephemeral':
448
314
  msg.message = {
449
315
  protocolMessage: {
450
- type: proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
316
+ type: WAProto_1.proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
451
317
  ephemeralExpiration: +(child.attrs.expiration || 0)
452
318
  }
453
319
  };
454
320
  break;
455
321
  case 'modify':
456
- const oldNumber = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid);
322
+ const oldNumber = (0, WABinary_1.getBinaryNodeChildren)(child, 'participant').map(p => p.attrs.jid);
457
323
  msg.messageStubParameters = oldNumber || [];
458
- msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER;
324
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER;
459
325
  break;
460
326
  case 'promote':
461
327
  case 'demote':
@@ -463,90 +329,121 @@ export const makeMessagesRecvSocket = (config) => {
463
329
  case 'add':
464
330
  case 'leave':
465
331
  const stubType = `GROUP_PARTICIPANT_${child.tag.toUpperCase()}`;
466
- msg.messageStubType = WAMessageStubType[stubType];
467
- const participants = getBinaryNodeChildren(child, 'participant').map(({ attrs }) => {
468
- // TODO: Store LID MAPPINGS
469
- return {
470
- id: attrs.jid,
471
- phoneNumber: isLidUser(attrs.jid) && isPnUser(attrs.phone_number) ? attrs.phone_number : undefined,
472
- lid: isPnUser(attrs.jid) && isLidUser(attrs.lid) ? attrs.lid : undefined,
473
- admin: (attrs.type || null)
474
- };
475
- });
332
+ msg.messageStubType = Types_1.WAMessageStubType[stubType];
333
+ const participants = (0, WABinary_1.getBinaryNodeChildren)(child, 'participant').map(p => p.attrs.jid);
476
334
  if (participants.length === 1 &&
477
335
  // if recv. "remove" message and sender removed themselves
478
336
  // mark as left
479
- (areJidsSameUser(participants[0].id, actingParticipantLid) ||
480
- areJidsSameUser(participants[0].id, actingParticipantPn)) &&
337
+ (0, WABinary_1.areJidsSameUser)(participants[0], participant) &&
481
338
  child.tag === 'remove') {
482
- msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_LEAVE;
339
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_PARTICIPANT_LEAVE;
483
340
  }
484
- msg.messageStubParameters = participants.map(a => JSON.stringify(a));
341
+ msg.messageStubParameters = participants;
485
342
  break;
486
343
  case 'subject':
487
- msg.messageStubType = WAMessageStubType.GROUP_CHANGE_SUBJECT;
344
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT;
488
345
  msg.messageStubParameters = [child.attrs.subject];
489
346
  break;
490
347
  case 'description':
491
- const description = getBinaryNodeChild(child, 'body')?.content?.toString();
492
- msg.messageStubType = WAMessageStubType.GROUP_CHANGE_DESCRIPTION;
348
+ const description = (_d = (_c = (0, WABinary_1.getBinaryNodeChild)(child, 'body')) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d.toString();
349
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_DESCRIPTION;
493
350
  msg.messageStubParameters = description ? [description] : undefined;
494
351
  break;
495
352
  case 'announcement':
496
353
  case 'not_announcement':
497
- msg.messageStubType = WAMessageStubType.GROUP_CHANGE_ANNOUNCE;
498
- msg.messageStubParameters = [child.tag === 'announcement' ? 'on' : 'off'];
354
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE;
355
+ msg.messageStubParameters = [(child.tag === 'announcement') ? 'on' : 'off'];
499
356
  break;
500
357
  case 'locked':
501
358
  case 'unlocked':
502
- msg.messageStubType = WAMessageStubType.GROUP_CHANGE_RESTRICT;
503
- msg.messageStubParameters = [child.tag === 'locked' ? 'on' : 'off'];
359
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_RESTRICT;
360
+ msg.messageStubParameters = [(child.tag === 'locked') ? 'on' : 'off'];
504
361
  break;
505
362
  case 'invite':
506
- msg.messageStubType = WAMessageStubType.GROUP_CHANGE_INVITE_LINK;
363
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_INVITE_LINK;
507
364
  msg.messageStubParameters = [child.attrs.code];
508
365
  break;
509
366
  case 'member_add_mode':
510
367
  const addMode = child.content;
511
368
  if (addMode) {
512
- msg.messageStubType = WAMessageStubType.GROUP_MEMBER_ADD_MODE;
369
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBER_ADD_MODE;
513
370
  msg.messageStubParameters = [addMode.toString()];
514
371
  }
515
372
  break;
516
373
  case 'membership_approval_mode':
517
- const approvalMode = getBinaryNodeChild(child, 'group_join');
374
+ const approvalMode = (0, WABinary_1.getBinaryNodeChild)(child, 'group_join');
518
375
  if (approvalMode) {
519
- msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE;
376
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE;
520
377
  msg.messageStubParameters = [approvalMode.attrs.state];
521
378
  }
522
379
  break;
523
380
  case 'created_membership_requests':
524
- msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
525
- msg.messageStubParameters = [
526
- JSON.stringify({ lid: affectedParticipantLid, pn: affectedParticipantPn }),
527
- 'created',
528
- child.attrs.request_method
529
- ];
381
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
382
+ msg.messageStubParameters = [participantJid, 'created', child.attrs.request_method];
530
383
  break;
531
384
  case 'revoked_membership_requests':
532
- const isDenied = areJidsSameUser(affectedParticipantLid, actingParticipantLid);
533
- // TODO: LIDMAPPING SUPPORT
534
- msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
535
- msg.messageStubParameters = [
536
- JSON.stringify({ lid: affectedParticipantLid, pn: affectedParticipantPn }),
537
- isDenied ? 'revoked' : 'rejected'
538
- ];
385
+ const isDenied = (0, WABinary_1.areJidsSameUser)(participantJid, participant);
386
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
387
+ msg.messageStubParameters = [participantJid, isDenied ? 'revoked' : 'rejected'];
388
+ break;
539
389
  break;
390
+ default:
391
+ // console.log("BAILEYS-DEBUG:", JSON.stringify({ ...child, content: Buffer.isBuffer(child.content) ? child.content.toString() : child.content, participant }, null, 2))
392
+ }
393
+ };
394
+ const handleNewsletterNotification = (id, node) => {
395
+ const messages = (0, WABinary_1.getBinaryNodeChild)(node, 'messages');
396
+ const message = (0, WABinary_1.getBinaryNodeChild)(messages, 'message');
397
+ const serverId = message.attrs.server_id;
398
+ const reactionsList = (0, WABinary_1.getBinaryNodeChild)(message, 'reactions');
399
+ const viewsList = (0, WABinary_1.getBinaryNodeChildren)(message, 'views_count');
400
+ if (reactionsList) {
401
+ const reactions = (0, WABinary_1.getBinaryNodeChildren)(reactionsList, 'reaction');
402
+ if (reactions.length === 0) {
403
+ ev.emit('newsletter.reaction', { id, 'server_id': serverId, reaction: { removed: true } });
404
+ }
405
+ reactions.forEach(item => {
406
+ var _a, _b;
407
+ ev.emit('newsletter.reaction', { id, 'server_id': serverId, reaction: { code: (_a = item.attrs) === null || _a === void 0 ? void 0 : _a.code, count: +((_b = item.attrs) === null || _b === void 0 ? void 0 : _b.count) } });
408
+ });
409
+ }
410
+ if (viewsList.length) {
411
+ viewsList.forEach(item => {
412
+ ev.emit('newsletter.view', { id, 'server_id': serverId, count: +item.attrs.count });
413
+ });
414
+ }
415
+ };
416
+ const handleMexNewsletterNotification = (id, node) => {
417
+ var _a;
418
+ const operation = node === null || node === void 0 ? void 0 : node.attrs.op_name;
419
+ const content = JSON.parse((_a = node === null || node === void 0 ? void 0 : node.content) === null || _a === void 0 ? void 0 : _a.toString());
420
+ let contentPath;
421
+ if (operation === Types_1.MexOperations.PROMOTE || operation === Types_1.MexOperations.DEMOTE) {
422
+ let action;
423
+ if (operation === Types_1.MexOperations.PROMOTE) {
424
+ action = 'promote';
425
+ contentPath = content.data[Types_1.XWAPaths.PROMOTE];
426
+ }
427
+ if (operation === Types_1.MexOperations.DEMOTE) {
428
+ action = 'demote';
429
+ contentPath = content.data[Types_1.XWAPaths.DEMOTE];
430
+ }
431
+ ev.emit('newsletter-participants.update', { id, author: contentPath.actor.pn, user: contentPath.user.pn, new_role: contentPath.user_new_role, action });
432
+ }
433
+ if (operation === Types_1.MexOperations.UPDATE) {
434
+ contentPath = content.data[Types_1.XWAPaths.METADATA_UPDATE];
435
+ ev.emit('newsletter-settings.update', { id, update: contentPath.thread_metadata.settings });
540
436
  }
541
437
  };
542
438
  const processNotification = async (node) => {
439
+ var _a, _b;
543
440
  const result = {};
544
- const [child] = getAllBinaryNodeChildren(node);
441
+ const [child] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
545
442
  const nodeType = node.attrs.type;
546
- const from = jidNormalizedUser(node.attrs.from);
443
+ const from = (0, WABinary_1.jidNormalizedUser)(node.attrs.from);
547
444
  switch (nodeType) {
548
445
  case 'privacy_token':
549
- const tokenList = getBinaryNodeChildren(child, 'token');
446
+ const tokenList = (0, WABinary_1.getBinaryNodeChildren)(child, 'token');
550
447
  for (const { attrs, content } of tokenList) {
551
448
  const jid = attrs.jid;
552
449
  ev.emit('chats.update', [
@@ -559,57 +456,52 @@ export const makeMessagesRecvSocket = (config) => {
559
456
  }
560
457
  break;
561
458
  case 'newsletter':
562
- await handleNewsletterNotification(node);
459
+ handleNewsletterNotification(node.attrs.from, child);
563
460
  break;
564
461
  case 'mex':
565
- await handleMexNewsletterNotification(node);
462
+ handleMexNewsletterNotification(node.attrs.from, child);
566
463
  break;
567
464
  case 'w:gp2':
568
- // TODO: HANDLE PARTICIPANT_PN
569
- handleGroupNotification(node, child, result);
465
+ handleGroupNotification(node.attrs.participant, child, result);
570
466
  break;
571
467
  case 'mediaretry':
572
- const event = decodeMediaRetryNode(node);
468
+ const event = (0, Utils_1.decodeMediaRetryNode)(node);
573
469
  ev.emit('messages.media-update', [event]);
574
470
  break;
575
471
  case 'encrypt':
576
472
  await handleEncryptNotification(node);
577
473
  break;
578
474
  case 'devices':
579
- const devices = getBinaryNodeChildren(child, 'device');
580
- if (areJidsSameUser(child.attrs.jid, authState.creds.me.id) ||
581
- areJidsSameUser(child.attrs.lid, authState.creds.me.lid)) {
582
- const deviceData = devices.map(d => ({ id: d.attrs.jid, lid: d.attrs.lid }));
583
- logger.info({ deviceData }, 'my own devices changed');
475
+ const devices = (0, WABinary_1.getBinaryNodeChildren)(child, 'device');
476
+ if ((0, WABinary_1.areJidsSameUser)(child.attrs.jid, authState.creds.me.id)) {
477
+ const deviceJids = devices.map(d => d.attrs.jid);
478
+ logger.info({ deviceJids }, 'got my own devices');
584
479
  }
585
- //TODO: drop a new event, add hashes
586
480
  break;
587
481
  case 'server_sync':
588
- const update = getBinaryNodeChild(node, 'collection');
482
+ const update = (0, WABinary_1.getBinaryNodeChild)(node, 'collection');
589
483
  if (update) {
590
484
  const name = update.attrs.name;
591
485
  await resyncAppState([name], false);
592
486
  }
593
487
  break;
594
488
  case 'picture':
595
- const setPicture = getBinaryNodeChild(node, 'set');
596
- const delPicture = getBinaryNodeChild(node, 'delete');
597
- ev.emit('contacts.update', [
598
- {
599
- id: jidNormalizedUser(node?.attrs?.from) || (setPicture || delPicture)?.attrs?.hash || '',
489
+ const setPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'set');
490
+ const delPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'delete');
491
+ ev.emit('contacts.update', [{
492
+ id: from || ((_b = (_a = (setPicture || delPicture)) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.hash) || '',
600
493
  imgUrl: setPicture ? 'changed' : 'removed'
601
- }
602
- ]);
603
- if (isJidGroup(from)) {
494
+ }]);
495
+ if ((0, WABinary_1.isJidGroup)(from)) {
604
496
  const node = setPicture || delPicture;
605
- result.messageStubType = WAMessageStubType.GROUP_CHANGE_ICON;
497
+ result.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_ICON;
606
498
  if (setPicture) {
607
499
  result.messageStubParameters = [setPicture.attrs.id];
608
500
  }
609
- result.participant = node?.attrs.author;
501
+ result.participant = node === null || node === void 0 ? void 0 : node.attrs.author;
610
502
  result.key = {
611
- ...(result.key || {}),
612
- participant: setPicture?.attrs.author
503
+ ...result.key || {},
504
+ participant: setPicture === null || setPicture === void 0 ? void 0 : setPicture.attrs.author
613
505
  };
614
506
  }
615
507
  break;
@@ -623,48 +515,44 @@ export const makeMessagesRecvSocket = (config) => {
623
515
  ...authState.creds.accountSettings,
624
516
  defaultDisappearingMode: {
625
517
  ephemeralExpiration: newDuration,
626
- ephemeralSettingTimestamp: timestamp
627
- }
518
+ ephemeralSettingTimestamp: timestamp,
519
+ },
628
520
  }
629
521
  });
630
522
  }
631
523
  else if (child.tag === 'blocklist') {
632
- const blocklists = getBinaryNodeChildren(child, 'item');
524
+ const blocklists = (0, WABinary_1.getBinaryNodeChildren)(child, 'item');
633
525
  for (const { attrs } of blocklists) {
634
526
  const blocklist = [attrs.jid];
635
- const type = attrs.action === 'block' ? 'add' : 'remove';
527
+ const type = (attrs.action === 'block') ? 'add' : 'remove';
636
528
  ev.emit('blocklist.update', { blocklist, type });
637
529
  }
638
530
  }
639
531
  break;
640
532
  case 'link_code_companion_reg':
641
- const linkCodeCompanionReg = getBinaryNodeChild(node, 'link_code_companion_reg');
642
- const ref = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'link_code_pairing_ref'));
643
- const primaryIdentityPublicKey = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'primary_identity_pub'));
644
- const primaryEphemeralPublicKeyWrapped = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'link_code_pairing_wrapped_primary_ephemeral_pub'));
533
+ const linkCodeCompanionReg = (0, WABinary_1.getBinaryNodeChild)(node, 'link_code_companion_reg');
534
+ const ref = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_ref'));
535
+ const primaryIdentityPublicKey = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'primary_identity_pub'));
536
+ const primaryEphemeralPublicKeyWrapped = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_wrapped_primary_ephemeral_pub'));
645
537
  const codePairingPublicKey = await decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped);
646
- const companionSharedKey = Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey);
647
- const random = randomBytes(32);
648
- const linkCodeSalt = randomBytes(32);
649
- const linkCodePairingExpanded = await hkdf(companionSharedKey, 32, {
538
+ const companionSharedKey = Utils_1.Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey);
539
+ const random = (0, crypto_1.randomBytes)(32);
540
+ const linkCodeSalt = (0, crypto_1.randomBytes)(32);
541
+ const linkCodePairingExpanded = await (0, Utils_1.hkdf)(companionSharedKey, 32, {
650
542
  salt: linkCodeSalt,
651
543
  info: 'link_code_pairing_key_bundle_encryption_key'
652
544
  });
653
- const encryptPayload = Buffer.concat([
654
- Buffer.from(authState.creds.signedIdentityKey.public),
655
- primaryIdentityPublicKey,
656
- random
657
- ]);
658
- const encryptIv = randomBytes(12);
659
- const encrypted = aesEncryptGCM(encryptPayload, linkCodePairingExpanded, encryptIv, Buffer.alloc(0));
545
+ const encryptPayload = Buffer.concat([Buffer.from(authState.creds.signedIdentityKey.public), primaryIdentityPublicKey, random]);
546
+ const encryptIv = (0, crypto_1.randomBytes)(12);
547
+ const encrypted = (0, Utils_1.aesEncryptGCM)(encryptPayload, linkCodePairingExpanded, encryptIv, Buffer.alloc(0));
660
548
  const encryptedPayload = Buffer.concat([linkCodeSalt, encryptIv, encrypted]);
661
- const identitySharedKey = Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey);
549
+ const identitySharedKey = Utils_1.Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey);
662
550
  const identityPayload = Buffer.concat([companionSharedKey, identitySharedKey, random]);
663
- authState.creds.advSecretKey = (await hkdf(identityPayload, 32, { info: 'adv_secret' })).toString('base64');
551
+ authState.creds.advSecretKey = (await (0, Utils_1.hkdf)(identityPayload, 32, { info: 'adv_secret' })).toString('base64');
664
552
  await query({
665
553
  tag: 'iq',
666
554
  attrs: {
667
- to: S_WHATSAPP_NET,
555
+ to: WABinary_1.S_WHATSAPP_NET,
668
556
  type: 'set',
669
557
  id: sock.generateMessageTag(),
670
558
  xmlns: 'md'
@@ -674,7 +562,7 @@ export const makeMessagesRecvSocket = (config) => {
674
562
  tag: 'link_code_companion_reg',
675
563
  attrs: {
676
564
  jid: authState.creds.me.id,
677
- stage: 'companion_finish'
565
+ stage: 'companion_finish',
678
566
  },
679
567
  content: [
680
568
  {
@@ -706,90 +594,44 @@ export const makeMessagesRecvSocket = (config) => {
706
594
  async function decipherLinkPublicKey(data) {
707
595
  const buffer = toRequiredBuffer(data);
708
596
  const salt = buffer.slice(0, 32);
709
- const secretKey = await derivePairingCodeKey(authState.creds.pairingCode, salt);
597
+ const secretKey = await (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
710
598
  const iv = buffer.slice(32, 48);
711
599
  const payload = buffer.slice(48, 80);
712
- return aesDecryptCTR(payload, secretKey, iv);
600
+ return (0, Utils_1.aesDecryptCTR)(payload, secretKey, iv);
713
601
  }
714
602
  function toRequiredBuffer(data) {
715
603
  if (data === undefined) {
716
- throw new Boom('Invalid buffer', { statusCode: 400 });
604
+ throw new boom_1.Boom('Invalid buffer', { statusCode: 400 });
717
605
  }
718
606
  return data instanceof Buffer ? data : Buffer.from(data);
719
607
  }
720
- const willSendMessageAgain = async (id, participant) => {
608
+ const willSendMessageAgain = (id, participant) => {
721
609
  const key = `${id}:${participant}`;
722
- const retryCount = (await msgRetryCache.get(key)) || 0;
610
+ const retryCount = msgRetryCache.get(key) || 0;
723
611
  return retryCount < maxMsgRetryCount;
724
612
  };
725
- const updateSendMessageAgainCount = async (id, participant) => {
613
+ const updateSendMessageAgainCount = (id, participant) => {
726
614
  const key = `${id}:${participant}`;
727
- const newValue = ((await msgRetryCache.get(key)) || 0) + 1;
728
- await msgRetryCache.set(key, newValue);
615
+ const newValue = (msgRetryCache.get(key) || 0) + 1;
616
+ msgRetryCache.set(key, newValue);
729
617
  };
730
618
  const sendMessagesAgain = async (key, ids, retryNode) => {
619
+ var _a;
620
+ // todo: implement a cache to store the last 256 sent messages (copy whatsmeow)
621
+ const msgs = await Promise.all(ids.map(id => getMessage({ ...key, id })));
731
622
  const remoteJid = key.remoteJid;
732
623
  const participant = key.participant || remoteJid;
733
- const retryCount = +retryNode.attrs.count || 1;
734
- // Try to get messages from cache first, then fallback to getMessage
735
- const msgs = [];
736
- for (const id of ids) {
737
- let msg;
738
- // Try to get from retry cache first if enabled
739
- if (messageRetryManager) {
740
- const cachedMsg = messageRetryManager.getRecentMessage(remoteJid, id);
741
- if (cachedMsg) {
742
- msg = cachedMsg.message;
743
- logger.debug({ jid: remoteJid, id }, 'found message in retry cache');
744
- // Mark retry as successful since we found the message
745
- messageRetryManager.markRetrySuccess(id);
746
- }
747
- }
748
- // Fallback to getMessage if not found in cache
749
- if (!msg) {
750
- msg = await getMessage({ ...key, id });
751
- if (msg) {
752
- logger.debug({ jid: remoteJid, id }, 'found message via getMessage');
753
- // Also mark as successful if found via getMessage
754
- if (messageRetryManager) {
755
- messageRetryManager.markRetrySuccess(id);
756
- }
757
- }
758
- }
759
- msgs.push(msg);
760
- }
761
624
  // if it's the primary jid sending the request
762
625
  // just re-send the message to everyone
763
626
  // prevents the first message decryption failure
764
- const sendToAll = !jidDecode(participant)?.device;
765
- // Check if we should recreate session for this retry
766
- let shouldRecreateSession = false;
767
- let recreateReason = '';
768
- if (enableAutoSessionRecreation && messageRetryManager) {
769
- try {
770
- const sessionId = signalRepository.jidToSignalProtocolAddress(participant);
771
- const hasSession = await signalRepository.validateSession(participant);
772
- const result = messageRetryManager.shouldRecreateSession(participant, retryCount, hasSession.exists);
773
- shouldRecreateSession = result.recreate;
774
- recreateReason = result.reason;
775
- if (shouldRecreateSession) {
776
- logger.debug({ participant, retryCount, reason: recreateReason }, 'recreating session for outgoing retry');
777
- await authState.keys.set({ session: { [sessionId]: null } });
778
- }
779
- }
780
- catch (error) {
781
- logger.warn({ error, participant }, 'failed to check session recreation for outgoing retry');
782
- }
783
- }
784
- await assertSessions([participant]);
785
- if (isJidGroup(remoteJid)) {
627
+ const sendToAll = !((_a = (0, WABinary_1.jidDecode)(participant)) === null || _a === void 0 ? void 0 : _a.device);
628
+ await assertSessions([participant], true);
629
+ if ((0, WABinary_1.isJidGroup)(remoteJid)) {
786
630
  await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } });
787
631
  }
788
- logger.debug({ participant, sendToAll, shouldRecreateSession, recreateReason }, 'forced new session for retry recp');
632
+ logger.debug({ participant, sendToAll }, 'forced new session for retry recp');
789
633
  for (const [i, msg] of msgs.entries()) {
790
- if (!ids[i])
791
- continue;
792
- if (msg && (await willSendMessageAgain(ids[i], participant))) {
634
+ if (msg) {
793
635
  updateSendMessageAgainCount(ids[i], participant);
794
636
  const msgRelayOpts = { messageId: ids[i] };
795
637
  if (sendToAll) {
@@ -809,10 +651,11 @@ export const makeMessagesRecvSocket = (config) => {
809
651
  }
810
652
  };
811
653
  const handleReceipt = async (node) => {
654
+ var _a, _b;
812
655
  const { attrs, content } = node;
813
656
  const isLid = attrs.from.includes('lid');
814
- const isNodeFromMe = areJidsSameUser(attrs.participant || attrs.from, isLid ? authState.creds.me?.lid : authState.creds.me?.id);
815
- const remoteJid = !isNodeFromMe || isJidGroup(attrs.from) ? attrs.from : attrs.recipient;
657
+ const isNodeFromMe = (0, WABinary_1.areJidsSameUser)(attrs.participant || attrs.from, isLid ? (_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.lid : (_b = authState.creds.me) === null || _b === void 0 ? void 0 : _b.id);
658
+ const remoteJid = !isNodeFromMe || (0, WABinary_1.isJidGroup)(attrs.from) ? attrs.from : attrs.recipient;
816
659
  const fromMe = !attrs.recipient || ((attrs.type === 'retry' || attrs.type === 'sender') && isNodeFromMe);
817
660
  const key = {
818
661
  remoteJid,
@@ -820,31 +663,33 @@ export const makeMessagesRecvSocket = (config) => {
820
663
  fromMe,
821
664
  participant: attrs.participant
822
665
  };
823
- if (shouldIgnoreJid(remoteJid) && remoteJid !== S_WHATSAPP_NET) {
666
+ if (shouldIgnoreJid(remoteJid) && remoteJid !== '@s.whatsapp.net') {
824
667
  logger.debug({ remoteJid }, 'ignoring receipt from jid');
825
668
  await sendMessageAck(node);
826
669
  return;
827
670
  }
828
671
  const ids = [attrs.id];
829
672
  if (Array.isArray(content)) {
830
- const items = getBinaryNodeChildren(content[0], 'item');
673
+ const items = (0, WABinary_1.getBinaryNodeChildren)(content[0], 'item');
831
674
  ids.push(...items.map(i => i.attrs.id));
832
675
  }
833
676
  try {
834
677
  await Promise.all([
835
678
  processingMutex.mutex(async () => {
836
- const status = getStatusFromReceiptType(attrs.type);
679
+ const status = (0, Utils_1.getStatusFromReceiptType)(attrs.type);
837
680
  if (typeof status !== 'undefined' &&
681
+ (
838
682
  // basically, we only want to know when a message from us has been delivered to/read by the other person
839
683
  // or another device of ours has read some messages
840
- (status >= proto.WebMessageInfo.Status.SERVER_ACK || !isNodeFromMe)) {
841
- if (isJidGroup(remoteJid) || isJidStatusBroadcast(remoteJid)) {
684
+ status >= WAProto_1.proto.WebMessageInfo.Status.SERVER_ACK ||
685
+ !isNodeFromMe)) {
686
+ if ((0, WABinary_1.isJidGroup)(remoteJid) || (0, WABinary_1.isJidStatusBroadcast)(remoteJid)) {
842
687
  if (attrs.participant) {
843
- const updateKey = status === proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
688
+ const updateKey = status === WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
844
689
  ev.emit('message-receipt.update', ids.map(id => ({
845
690
  key: { ...key, id },
846
691
  receipt: {
847
- userJid: jidNormalizedUser(attrs.participant),
692
+ userJid: (0, WABinary_1.jidNormalizedUser)(attrs.participant),
848
693
  [updateKey]: +attrs.t
849
694
  }
850
695
  })));
@@ -860,16 +705,15 @@ export const makeMessagesRecvSocket = (config) => {
860
705
  if (attrs.type === 'retry') {
861
706
  // correctly set who is asking for the retry
862
707
  key.participant = key.participant || attrs.from;
863
- const retryNode = getBinaryNodeChild(node, 'retry');
864
- if (ids[0] && key.participant && (await willSendMessageAgain(ids[0], key.participant))) {
708
+ const retryNode = (0, WABinary_1.getBinaryNodeChild)(node, 'retry');
709
+ if (willSendMessageAgain(ids[0], key.participant)) {
865
710
  if (key.fromMe) {
866
711
  try {
867
- updateSendMessageAgainCount(ids[0], key.participant);
868
712
  logger.debug({ attrs, key }, 'recv retry request');
869
713
  await sendMessagesAgain(key, ids, retryNode);
870
714
  }
871
715
  catch (error) {
872
- logger.error({ key, ids, trace: error instanceof Error ? error.stack : 'Unknown error' }, 'error in sending message again');
716
+ logger.error({ key, ids, trace: error.stack }, 'error in sending message again');
873
717
  }
874
718
  }
875
719
  else {
@@ -889,7 +733,7 @@ export const makeMessagesRecvSocket = (config) => {
889
733
  };
890
734
  const handleNotification = async (node) => {
891
735
  const remoteJid = node.attrs.from;
892
- if (shouldIgnoreJid(remoteJid) && remoteJid !== S_WHATSAPP_NET) {
736
+ if (shouldIgnoreJid(remoteJid) && remoteJid !== '@s.whatsapp.net') {
893
737
  logger.debug({ remoteJid, id: node.attrs.id }, 'ignored notification');
894
738
  await sendMessageAck(node);
895
739
  return;
@@ -897,22 +741,20 @@ export const makeMessagesRecvSocket = (config) => {
897
741
  try {
898
742
  await Promise.all([
899
743
  processingMutex.mutex(async () => {
744
+ var _a;
900
745
  const msg = await processNotification(node);
901
746
  if (msg) {
902
- const fromMe = areJidsSameUser(node.attrs.participant || remoteJid, authState.creds.me.id);
903
- const { senderAlt: participantAlt, addressingMode } = extractAddressingContext(node);
747
+ const fromMe = (0, WABinary_1.areJidsSameUser)(node.attrs.participant || remoteJid, authState.creds.me.id);
904
748
  msg.key = {
905
749
  remoteJid,
906
750
  fromMe,
907
751
  participant: node.attrs.participant,
908
- participantAlt,
909
- addressingMode,
910
752
  id: node.attrs.id,
911
753
  ...(msg.key || {})
912
754
  };
913
- msg.participant ?? (msg.participant = node.attrs.participant);
755
+ (_a = msg.participant) !== null && _a !== void 0 ? _a : (msg.participant = node.attrs.participant);
914
756
  msg.messageTimestamp = +node.attrs.t;
915
- const fullMsg = proto.WebMessageInfo.fromObject(msg);
757
+ const fullMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
916
758
  await upsertMessage(fullMsg, 'append');
917
759
  }
918
760
  })
@@ -923,152 +765,185 @@ export const makeMessagesRecvSocket = (config) => {
923
765
  }
924
766
  };
925
767
  const handleMessage = async (node) => {
926
- if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !== S_WHATSAPP_NET) {
768
+ var _a, _b, _c;
769
+ if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !== '@s.whatsapp.net') {
927
770
  logger.debug({ key: node.attrs.key }, 'ignored message');
928
- await sendMessageAck(node, NACK_REASONS.UnhandledError);
771
+ await sendMessageAck(node);
929
772
  return;
930
773
  }
931
- const encNode = getBinaryNodeChild(node, 'enc');
774
+ const encNode = (0, WABinary_1.getBinaryNodeChild)(node, 'enc');
932
775
  // TODO: temporary fix for crashes and issues resulting of failed msmsg decryption
933
776
  if (encNode && encNode.attrs.type === 'msmsg') {
934
777
  logger.debug({ key: node.attrs.key }, 'ignored msmsg');
935
- await sendMessageAck(node, NACK_REASONS.MissingMessageSecret);
778
+ await sendMessageAck(node);
936
779
  return;
937
780
  }
938
- const { fullMessage: msg, category, author, decrypt } = decryptMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
939
- const alt = msg.key.participantAlt || msg.key.remoteJidAlt;
940
- // store new mappings we didn't have before
941
- if (!!alt) {
942
- const altServer = jidDecode(alt)?.server;
943
- const primaryJid = msg.key.participant || msg.key.remoteJid;
944
- if (altServer === 'lid') {
945
- if (!(await signalRepository.lidMapping.getPNForLID(alt))) {
946
- await signalRepository.lidMapping.storeLIDPNMappings([{ lid: alt, pn: primaryJid }]);
947
- await signalRepository.migrateSession(primaryJid, alt);
948
- }
781
+ let response;
782
+ if ((0, WABinary_1.getBinaryNodeChild)(node, 'unavailable') && !encNode) {
783
+ await sendMessageAck(node);
784
+ const { key } = (0, Utils_1.decodeMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '').fullMessage;
785
+ response = await requestPlaceholderResend(key);
786
+ if (response === 'RESOLVED') {
787
+ return;
949
788
  }
950
- else {
951
- await signalRepository.lidMapping.storeLIDPNMappings([{ lid: primaryJid, pn: alt }]);
952
- await signalRepository.migrateSession(alt, primaryJid);
789
+ logger.debug('received unavailable message, acked and requested resend from phone');
790
+ }
791
+ else {
792
+ if (placeholderResendCache.get(node.attrs.id)) {
793
+ placeholderResendCache.del(node.attrs.id);
953
794
  }
954
795
  }
955
- if (msg.key?.remoteJid && msg.key?.id && messageRetryManager) {
956
- messageRetryManager.addRecentMessage(msg.key.remoteJid, msg.key.id, msg.message);
957
- logger.debug({
958
- jid: msg.key.remoteJid,
959
- id: msg.key.id
960
- }, 'Added message to recent cache for retry receipts');
796
+ const { fullMessage: msg, category, author, decrypt } = (0, Utils_1.decryptMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
797
+ if (response && ((_a = msg === null || msg === void 0 ? void 0 : msg.messageStubParameters) === null || _a === void 0 ? void 0 : _a[0]) === Utils_1.NO_MESSAGE_FOUND_ERROR_TEXT) {
798
+ msg.messageStubParameters = [Utils_1.NO_MESSAGE_FOUND_ERROR_TEXT, response];
799
+ }
800
+ if (((_c = (_b = msg.message) === null || _b === void 0 ? void 0 : _b.protocolMessage) === null || _c === void 0 ? void 0 : _c.type) === WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER && node.attrs.sender_pn) {
801
+ ev.emit('chats.phoneNumberShare', { lid: node.attrs.from, jid: node.attrs.sender_pn });
961
802
  }
962
803
  try {
963
- await processingMutex.mutex(async () => {
964
- await decrypt();
965
- // message failed to decrypt
966
- if (msg.messageStubType === proto.WebMessageInfo.StubType.CIPHERTEXT) {
967
- if (msg?.messageStubParameters?.[0] === MISSING_KEYS_ERROR_TEXT) {
968
- return sendMessageAck(node, NACK_REASONS.ParsingError);
969
- }
970
- const errorMessage = msg?.messageStubParameters?.[0] || '';
971
- const isPreKeyError = errorMessage.includes('PreKey');
972
- logger.debug(`[handleMessage] Attempting retry request for failed decryption`);
973
- // Handle both pre-key and normal retries in single mutex
974
- retryMutex.mutex(async () => {
975
- try {
976
- if (!ws.isOpen) {
977
- logger.debug({ node }, 'Connection closed, skipping retry');
978
- return;
979
- }
980
- // Handle pre-key errors with upload and delay
981
- if (isPreKeyError) {
982
- logger.info({ error: errorMessage }, 'PreKey error detected, uploading and retrying');
983
- try {
984
- logger.debug('Uploading pre-keys for error recovery');
985
- await uploadPreKeys(5);
986
- logger.debug('Waiting for server to process new pre-keys');
987
- await delay(1000);
804
+ await Promise.all([
805
+ processingMutex.mutex(async () => {
806
+ var _a, _b, _c, _d, _e, _f;
807
+ await decrypt();
808
+ // message failed to decrypt
809
+ if (msg.messageStubType === WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT) {
810
+ if (((_a = msg === null || msg === void 0 ? void 0 : msg.messageStubParameters) === null || _a === void 0 ? void 0 : _a[0]) === Utils_1.MISSING_KEYS_ERROR_TEXT) {
811
+ return sendMessageAck(node, Utils_1.NACK_REASONS.ParsingError);
812
+ }
813
+ retryMutex.mutex(async () => {
814
+ if (ws.isOpen) {
815
+ if ((0, WABinary_1.getBinaryNodeChild)(node, 'unavailable')) {
816
+ return;
988
817
  }
989
- catch (uploadErr) {
990
- logger.error({ uploadErr }, 'Pre-key upload failed, proceeding with retry anyway');
818
+ const encNode = (0, WABinary_1.getBinaryNodeChild)(node, 'enc');
819
+ await sendRetryRequest(node, !encNode);
820
+ if (retryRequestDelayMs) {
821
+ await (0, Utils_1.delay)(retryRequestDelayMs);
991
822
  }
992
823
  }
993
- const encNode = getBinaryNodeChild(node, 'enc');
994
- await sendRetryRequest(node, !encNode);
995
- if (retryRequestDelayMs) {
996
- await delay(retryRequestDelayMs);
824
+ else {
825
+ logger.debug({ node }, 'connection closed, ignoring retry req');
997
826
  }
827
+ });
828
+ }
829
+ else {
830
+ // no type in the receipt => message delivered
831
+ let type = undefined;
832
+ if ((_b = msg.key.participant) === null || _b === void 0 ? void 0 : _b.endsWith('@lid')) {
833
+ msg.key.participant = node.attrs.participant_pn || authState.creds.me.id;
998
834
  }
999
- catch (err) {
1000
- logger.error({ err, isPreKeyError }, 'Failed to handle retry, attempting basic retry');
1001
- // Still attempt retry even if pre-key upload failed
1002
- try {
1003
- const encNode = getBinaryNodeChild(node, 'enc');
1004
- await sendRetryRequest(node, !encNode);
835
+ if ((0, WABinary_1.isJidGroup)(msg.key.remoteJid) && ((_f = (_e = (_d = (_c = msg.message) === null || _c === void 0 ? void 0 : _c.extendedTextMessage) === null || _d === void 0 ? void 0 : _d.contextInfo) === null || _e === void 0 ? void 0 : _e.participant) === null || _f === void 0 ? void 0 : _f.endsWith('@lid'))) {
836
+ if (msg.message.extendedTextMessage.contextInfo) {
837
+ const metadata = await groupMetadata(msg.key.remoteJid);
838
+ const sender = msg.message.extendedTextMessage.contextInfo.participant;
839
+ const found = metadata.participants.find(p => p.id === sender);
840
+ msg.message.extendedTextMessage.contextInfo.participant = (found === null || found === void 0 ? void 0 : found.jid) || sender;
1005
841
  }
1006
- catch (retryErr) {
1007
- logger.error({ retryErr }, 'Failed to send retry after error handling');
842
+ }
843
+ if (!(0, WABinary_1.isJidGroup)(msg.key.remoteJid) && (0, WABinary_1.isLidUser)(msg.key.remoteJid)) {
844
+ msg.key.remoteJid = node.attrs.sender_pn || node.attrs.peer_recipient_pn;
845
+ }
846
+ let participant = msg.key.participant;
847
+ if (category === 'peer') { // special peer message
848
+ type = 'peer_msg';
849
+ }
850
+ else if (msg.key.fromMe) { // message was sent by us from a different device
851
+ type = 'sender';
852
+ // need to specially handle this case
853
+ if ((0, WABinary_1.isJidUser)(msg.key.remoteJid)) {
854
+ participant = author;
1008
855
  }
1009
856
  }
1010
- await sendMessageAck(node, NACK_REASONS.UnhandledError);
1011
- });
1012
- }
1013
- else {
1014
- // no type in the receipt => message delivered
1015
- let type = undefined;
1016
- let participant = msg.key.participant;
1017
- if (category === 'peer') {
1018
- // special peer message
1019
- type = 'peer_msg';
1020
- }
1021
- else if (msg.key.fromMe) {
1022
- // message was sent by us from a different device
1023
- type = 'sender';
1024
- // need to specially handle this case
1025
- if (isLidUser(msg.key.remoteJid) || isLidUser(msg.key.remoteJidAlt)) {
1026
- participant = author; // TODO: investigate sending receipts to LIDs and not PNs
857
+ else if (!sendActiveReceipts) {
858
+ type = 'inactive';
859
+ }
860
+ await sendReceipt(msg.key.remoteJid, participant, [msg.key.id], type);
861
+ // send ack for history message
862
+ const isAnyHistoryMsg = (0, Utils_1.getHistoryMsg)(msg.message);
863
+ if (isAnyHistoryMsg) {
864
+ const jid = (0, WABinary_1.jidNormalizedUser)(msg.key.remoteJid);
865
+ await sendReceipt(jid, undefined, [msg.key.id], 'hist_sync');
1027
866
  }
1028
867
  }
1029
- else if (!sendActiveReceipts) {
1030
- type = 'inactive';
1031
- }
1032
- await sendReceipt(msg.key.remoteJid, participant, [msg.key.id], type);
1033
- // send ack for history message
1034
- const isAnyHistoryMsg = getHistoryMsg(msg.message);
1035
- if (isAnyHistoryMsg) {
1036
- const jid = jidNormalizedUser(msg.key.remoteJid);
1037
- await sendReceipt(jid, undefined, [msg.key.id], 'hist_sync');
1038
- }
1039
- }
1040
- cleanMessage(msg, authState.creds.me.id, authState.creds.me.lid);
1041
- await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify');
1042
- });
868
+ (0, Utils_1.cleanMessage)(msg, authState.creds.me.id);
869
+ await sendMessageAck(node);
870
+ await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify');
871
+ })
872
+ ]);
1043
873
  }
1044
874
  catch (error) {
1045
- logger.error({ error, node: binaryNodeToString(node) }, 'error in handling message');
875
+ logger.error({ error, node }, 'error in handling message');
876
+ }
877
+ };
878
+ const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
879
+ var _a;
880
+ if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
881
+ throw new boom_1.Boom('Not authenticated');
882
+ }
883
+ const pdoMessage = {
884
+ historySyncOnDemandRequest: {
885
+ chatJid: oldestMsgKey.remoteJid,
886
+ oldestMsgFromMe: oldestMsgKey.fromMe,
887
+ oldestMsgId: oldestMsgKey.id,
888
+ oldestMsgTimestampMs: oldestMsgTimestamp,
889
+ onDemandMsgCount: count
890
+ },
891
+ peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
892
+ };
893
+ return sendPeerDataOperationMessage(pdoMessage);
894
+ };
895
+ const requestPlaceholderResend = async (messageKey) => {
896
+ var _a;
897
+ if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
898
+ throw new boom_1.Boom('Not authenticated');
899
+ }
900
+ if (placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
901
+ logger.debug({ messageKey }, 'already requested resend');
902
+ return;
1046
903
  }
904
+ else {
905
+ placeholderResendCache.set(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id, true);
906
+ }
907
+ await (0, Utils_1.delay)(5000);
908
+ if (!placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
909
+ logger.debug({ messageKey }, 'message received while resend requested');
910
+ return 'RESOLVED';
911
+ }
912
+ const pdoMessage = {
913
+ placeholderMessageResendRequest: [{
914
+ messageKey
915
+ }],
916
+ peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
917
+ };
918
+ setTimeout(() => {
919
+ if (placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
920
+ logger.debug({ messageKey }, 'PDO message without response after 15 seconds. Phone possibly offline');
921
+ placeholderResendCache.del(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id);
922
+ }
923
+ }, 15000);
924
+ return sendPeerDataOperationMessage(pdoMessage);
1047
925
  };
1048
926
  const handleCall = async (node) => {
1049
927
  const { attrs } = node;
1050
- const [infoChild] = getAllBinaryNodeChildren(node);
1051
- const status = getCallStatusFromNode(infoChild);
1052
- if (!infoChild) {
1053
- throw new Boom('Missing call info in call node');
1054
- }
928
+ const [infoChild] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
1055
929
  const callId = infoChild.attrs['call-id'];
1056
930
  const from = infoChild.attrs.from || infoChild.attrs['call-creator'];
931
+ const status = (0, Utils_1.getCallStatusFromNode)(infoChild);
1057
932
  const call = {
1058
933
  chatId: attrs.from,
1059
934
  from,
1060
935
  id: callId,
1061
936
  date: new Date(+attrs.t * 1000),
1062
937
  offline: !!attrs.offline,
1063
- status
938
+ status,
1064
939
  };
1065
940
  if (status === 'offer') {
1066
- call.isVideo = !!getBinaryNodeChild(infoChild, 'video');
941
+ call.isVideo = !!(0, WABinary_1.getBinaryNodeChild)(infoChild, 'video');
1067
942
  call.isGroup = infoChild.attrs.type === 'group' || !!infoChild.attrs['group-jid'];
1068
943
  call.groupJid = infoChild.attrs['group-jid'];
1069
- await callOfferCache.set(call.id, call);
944
+ callOfferCache.set(call.id, call);
1070
945
  }
1071
- const existingCall = await callOfferCache.get(call.id);
946
+ const existingCall = callOfferCache.get(call.id);
1072
947
  // use existing call info to populate this event
1073
948
  if (existingCall) {
1074
949
  call.isVideo = existingCall.isVideo;
@@ -1076,26 +951,34 @@ export const makeMessagesRecvSocket = (config) => {
1076
951
  }
1077
952
  // delete data once call has ended
1078
953
  if (status === 'reject' || status === 'accept' || status === 'timeout' || status === 'terminate') {
1079
- await callOfferCache.del(call.id);
954
+ callOfferCache.del(call.id);
1080
955
  }
1081
956
  ev.emit('call', [call]);
1082
957
  await sendMessageAck(node);
1083
958
  };
1084
959
  const handleBadAck = async ({ attrs }) => {
1085
- const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id };
1086
- // WARNING: REFRAIN FROM ENABLING THIS FOR NOW. IT WILL CAUSE A LOOP
1087
- // // current hypothesis is that if pash is sent in the ack
1088
- // // it means -- the message hasn't reached all devices yet
1089
- // // we'll retry sending the message here
1090
- // if(attrs.phash) {
1091
- // logger.info({ attrs }, 'received phash in ack, resending message...')
1092
- // const msg = await getMessage(key)
1093
- // if(msg) {
1094
- // await relayMessage(key.remoteJid!, msg, { messageId: key.id!, useUserDevicesCache: false })
1095
- // } else {
1096
- // logger.warn({ attrs }, 'could not send message again, as it was not found')
1097
- // }
1098
- // }
960
+ const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id, 'server_id': attrs === null || attrs === void 0 ? void 0 : attrs.server_id };
961
+ // current hypothesis is that if pash is sent in the ack
962
+ // it means -- the message hasn't reached all devices yet
963
+ // we'll retry sending the message here
964
+ if (attrs.phash) {
965
+ logger.info({ attrs }, 'received phash in ack, resending message...');
966
+ const cacheKey = `${key.remoteJid}:${key.id}`;
967
+ if ((msgRetryCache.get(cacheKey) || 0) >= maxMsgRetryCount) {
968
+ logger.warn({ attrs }, 'reached max retry count, not sending message again');
969
+ msgRetryCache.del(cacheKey);
970
+ return;
971
+ }
972
+ const retryCount = msgRetryCache.get(cacheKey) || 0;
973
+ const msg = await getMessage(key);
974
+ if (msg) {
975
+ await relayMessage(key.remoteJid, msg, { messageId: key.id, useUserDevicesCache: false });
976
+ msgRetryCache.set(cacheKey, retryCount + 1);
977
+ }
978
+ else {
979
+ logger.warn({ attrs }, 'could not send message again, as it was not found');
980
+ }
981
+ }
1099
982
  // error in acknowledgement,
1100
983
  // device could not display the message
1101
984
  if (attrs.error) {
@@ -1104,8 +987,10 @@ export const makeMessagesRecvSocket = (config) => {
1104
987
  {
1105
988
  key,
1106
989
  update: {
1107
- status: WAMessageStatus.ERROR,
1108
- messageStubParameters: [attrs.error]
990
+ status: Types_1.WAMessageStatus.ERROR,
991
+ messageStubParameters: [
992
+ attrs.error
993
+ ]
1109
994
  }
1110
995
  }
1111
996
  ]);
@@ -1118,7 +1003,8 @@ export const makeMessagesRecvSocket = (config) => {
1118
1003
  await execTask();
1119
1004
  ev.flush();
1120
1005
  function execTask() {
1121
- return exec(node, false).catch(err => onUnexpectedError(err, identifier));
1006
+ return exec(node, false)
1007
+ .catch(err => onUnexpectedError(err, identifier));
1122
1008
  }
1123
1009
  };
1124
1010
  const makeOfflineNodeProcessor = () => {
@@ -1176,12 +1062,10 @@ export const makeMessagesRecvSocket = (config) => {
1176
1062
  processNode('notification', node, 'handling notification', handleNotification);
1177
1063
  });
1178
1064
  ws.on('CB:ack,class:message', (node) => {
1179
- handleBadAck(node).catch(error => onUnexpectedError(error, 'handling bad ack'));
1065
+ handleBadAck(node)
1066
+ .catch(error => onUnexpectedError(error, 'handling bad ack'));
1180
1067
  });
1181
1068
  ev.on('call', ([call]) => {
1182
- if (!call) {
1183
- return;
1184
- }
1185
1069
  // missed call + group call notification message generation
1186
1070
  if (call.status === 'timeout' || (call.status === 'offer' && call.isGroup)) {
1187
1071
  const msg = {
@@ -1190,22 +1074,20 @@ export const makeMessagesRecvSocket = (config) => {
1190
1074
  id: call.id,
1191
1075
  fromMe: false
1192
1076
  },
1193
- messageTimestamp: unixTimestampSeconds(call.date)
1077
+ messageTimestamp: (0, Utils_1.unixTimestampSeconds)(call.date),
1194
1078
  };
1195
1079
  if (call.status === 'timeout') {
1196
1080
  if (call.isGroup) {
1197
- msg.messageStubType = call.isVideo
1198
- ? WAMessageStubType.CALL_MISSED_GROUP_VIDEO
1199
- : WAMessageStubType.CALL_MISSED_GROUP_VOICE;
1081
+ msg.messageStubType = call.isVideo ? Types_1.WAMessageStubType.CALL_MISSED_GROUP_VIDEO : Types_1.WAMessageStubType.CALL_MISSED_GROUP_VOICE;
1200
1082
  }
1201
1083
  else {
1202
- msg.messageStubType = call.isVideo ? WAMessageStubType.CALL_MISSED_VIDEO : WAMessageStubType.CALL_MISSED_VOICE;
1084
+ msg.messageStubType = call.isVideo ? Types_1.WAMessageStubType.CALL_MISSED_VIDEO : Types_1.WAMessageStubType.CALL_MISSED_VOICE;
1203
1085
  }
1204
1086
  }
1205
1087
  else {
1206
1088
  msg.message = { call: { callKey: Buffer.from(call.id) } };
1207
1089
  }
1208
- const protoMsg = proto.WebMessageInfo.fromObject(msg);
1090
+ const protoMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
1209
1091
  upsertMessage(protoMsg, call.offline ? 'append' : 'notify');
1210
1092
  }
1211
1093
  });
@@ -1220,9 +1102,9 @@ export const makeMessagesRecvSocket = (config) => {
1220
1102
  sendMessageAck,
1221
1103
  sendRetryRequest,
1222
1104
  rejectCall,
1105
+ offerCall,
1223
1106
  fetchMessageHistory,
1224
1107
  requestPlaceholderResend,
1225
- messageRetryManager
1226
1108
  };
1227
1109
  };
1228
- //# sourceMappingURL=messages-recv.js.map
1110
+ exports.makeMessagesRecvSocket = makeMessagesRecvSocket;