gifted-baileys 1.5.5 → 1.5.7

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 (251) hide show
  1. package/README.md +6 -1642
  2. package/WAProto/WAProto.proto +969 -88
  3. package/WAProto/index.d.ts +13199 -1260
  4. package/WAProto/index.js +124901 -74525
  5. package/lib/Defaults/baileys-version.json +3 -0
  6. package/lib/Defaults/index.d.ts +284 -0
  7. package/{src → lib}/Defaults/index.js +7 -14
  8. package/lib/Signal/libsignal.d.ts +3 -0
  9. package/lib/Signal/libsignal.js +161 -0
  10. package/lib/Socket/Client/abstract-socket-client.d.ts +15 -0
  11. package/lib/Socket/Client/index.d.ts +2 -0
  12. package/{src → lib}/Socket/Client/index.js +2 -3
  13. package/lib/Socket/Client/mobile-socket-client.d.ts +12 -0
  14. package/lib/Socket/Client/mobile-socket-client.js +65 -0
  15. package/lib/Socket/Client/types.d.ts +17 -0
  16. package/lib/Socket/Client/types.js +13 -0
  17. package/lib/Socket/Client/websocket.d.ts +12 -0
  18. package/lib/Socket/Client/websocket.js +62 -0
  19. package/lib/Socket/business.d.ts +170 -0
  20. package/{src → lib}/Socket/business.js +28 -33
  21. package/lib/Socket/chats.d.ts +81 -0
  22. package/{src → lib}/Socket/chats.js +174 -176
  23. package/lib/Socket/groups.d.ts +115 -0
  24. package/{src → lib}/Socket/groups.js +80 -68
  25. package/lib/Socket/index.d.ts +172 -0
  26. package/{src → lib}/Socket/index.js +4 -1
  27. package/lib/Socket/messages-recv.d.ts +158 -0
  28. package/{src → lib}/Socket/messages-recv.js +378 -211
  29. package/lib/Socket/messages-send.d.ts +155 -0
  30. package/{src → lib}/Socket/messages-send.js +452 -177
  31. package/lib/Socket/newsletter.d.ts +132 -0
  32. package/{src → lib}/Socket/newsletter.js +107 -98
  33. package/lib/Socket/registration.d.ts +264 -0
  34. package/{src → lib}/Socket/registration.js +56 -48
  35. package/lib/Socket/socket.d.ts +44 -0
  36. package/{src → lib}/Socket/socket.js +77 -77
  37. package/lib/Socket/usync.d.ts +37 -0
  38. package/lib/Socket/usync.js +70 -0
  39. package/lib/Store/index.d.ts +3 -0
  40. package/lib/Store/make-cache-manager-store.d.ts +14 -0
  41. package/{src → lib}/Store/make-cache-manager-store.js +25 -34
  42. package/lib/Store/make-in-memory-store.d.ts +118 -0
  43. package/{src → lib}/Store/make-in-memory-store.js +36 -32
  44. package/lib/Store/make-ordered-dictionary.d.ts +13 -0
  45. package/lib/Store/object-repository.d.ts +10 -0
  46. package/{src → lib}/Store/object-repository.js +1 -1
  47. package/lib/Types/Auth.d.ts +109 -0
  48. package/lib/Types/Call.d.ts +13 -0
  49. package/lib/Types/Chat.d.ts +107 -0
  50. package/{src/Types/Contact.ts → lib/Types/Contact.d.ts} +8 -9
  51. package/lib/Types/Events.d.ts +172 -0
  52. package/lib/Types/GroupMetadata.d.ts +56 -0
  53. package/lib/Types/Label.d.ts +46 -0
  54. package/{src/Types/LabelAssociation.ts → lib/Types/LabelAssociation.d.ts} +16 -22
  55. package/lib/Types/Message.d.ts +433 -0
  56. package/lib/Types/Newsletter.d.ts +92 -0
  57. package/lib/Types/Product.d.ts +78 -0
  58. package/lib/Types/Signal.d.ts +57 -0
  59. package/{src/Types/Socket.ts → lib/Types/Socket.d.ts} +61 -68
  60. package/lib/Types/State.d.ts +27 -0
  61. package/lib/Types/USync.d.ts +25 -0
  62. package/lib/Types/index.d.ts +66 -0
  63. package/lib/Utils/auth-utils.d.ts +18 -0
  64. package/{src → lib}/Utils/auth-utils.js +73 -90
  65. package/lib/Utils/baileys-event-stream.d.ts +16 -0
  66. package/lib/Utils/baileys-event-stream.js +63 -0
  67. package/lib/Utils/business.d.ts +22 -0
  68. package/{src → lib}/Utils/business.js +15 -43
  69. package/lib/Utils/chat-utils.d.ts +70 -0
  70. package/{src → lib}/Utils/chat-utils.js +87 -94
  71. package/lib/Utils/crypto.d.ts +40 -0
  72. package/{src → lib}/Utils/crypto.js +4 -2
  73. package/lib/Utils/decode-wa-message.d.ts +36 -0
  74. package/lib/Utils/decode-wa-message.js +226 -0
  75. package/lib/Utils/event-buffer.d.ts +35 -0
  76. package/{src → lib}/Utils/event-buffer.js +4 -13
  77. package/lib/Utils/generics.d.ts +88 -0
  78. package/{src → lib}/Utils/generics.js +67 -86
  79. package/lib/Utils/history.d.ts +19 -0
  80. package/{src → lib}/Utils/history.js +13 -39
  81. package/lib/Utils/index.d.ts +17 -0
  82. package/lib/Utils/link-preview.d.ts +21 -0
  83. package/{src → lib}/Utils/link-preview.js +17 -54
  84. package/lib/Utils/logger.d.ts +2 -0
  85. package/lib/Utils/lt-hash.d.ts +12 -0
  86. package/lib/Utils/make-mutex.d.ts +7 -0
  87. package/{src → lib}/Utils/make-mutex.js +4 -13
  88. package/lib/Utils/messages-media.d.ts +113 -0
  89. package/{src → lib}/Utils/messages-media.js +193 -255
  90. package/lib/Utils/messages.d.ts +77 -0
  91. package/{src → lib}/Utils/messages.js +588 -118
  92. package/lib/Utils/noise-handler.d.ts +20 -0
  93. package/lib/Utils/process-message.d.ts +41 -0
  94. package/{src → lib}/Utils/process-message.js +27 -30
  95. package/lib/Utils/signal.d.ts +33 -0
  96. package/{src → lib}/Utils/signal.js +25 -42
  97. package/lib/Utils/use-multi-file-auth-state.d.ts +12 -0
  98. package/{src → lib}/Utils/use-multi-file-auth-state.js +27 -28
  99. package/lib/Utils/validate-connection.d.ts +11 -0
  100. package/{src → lib}/Utils/validate-connection.js +40 -9
  101. package/lib/WABinary/constants.d.ts +27 -0
  102. package/lib/WABinary/decode.d.ts +6 -0
  103. package/lib/WABinary/encode.d.ts +2 -0
  104. package/{src → lib}/WABinary/encode.js +16 -10
  105. package/lib/WABinary/generic-utils.d.ts +14 -0
  106. package/lib/WABinary/index.d.ts +5 -0
  107. package/lib/WABinary/jid-utils.d.ts +31 -0
  108. package/lib/WABinary/types.d.ts +18 -0
  109. package/lib/WABinary/types.js +2 -0
  110. package/lib/WAM/BinaryInfo.d.ts +8 -0
  111. package/lib/WAM/constants.d.ts +38 -0
  112. package/lib/WAM/encode.d.ts +2 -0
  113. package/lib/WAM/index.d.ts +3 -0
  114. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
  115. package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
  116. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
  117. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
  118. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  119. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
  120. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  121. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  122. package/lib/WAUSync/Protocols/index.d.ts +4 -0
  123. package/lib/WAUSync/Protocols/index.js +20 -0
  124. package/lib/WAUSync/USyncQuery.d.ts +26 -0
  125. package/lib/WAUSync/USyncQuery.js +79 -0
  126. package/lib/WAUSync/USyncUser.d.ts +10 -0
  127. package/lib/WAUSync/USyncUser.js +22 -0
  128. package/lib/WAUSync/index.d.ts +3 -0
  129. package/lib/WAUSync/index.js +19 -0
  130. package/{src → lib}/index.js +1 -0
  131. package/package.json +26 -8
  132. package/LICENSE +0 -21
  133. package/src/Defaults/baileys-version.json +0 -3
  134. package/src/Defaults/index.ts +0 -131
  135. package/src/Signal/libsignal.js +0 -180
  136. package/src/Signal/libsignal.ts +0 -141
  137. package/src/Socket/Client/abstract-socket-client.ts +0 -19
  138. package/src/Socket/Client/index.ts +0 -3
  139. package/src/Socket/Client/mobile-socket-client.js +0 -78
  140. package/src/Socket/Client/mobile-socket-client.ts +0 -66
  141. package/src/Socket/Client/web-socket-client.js +0 -75
  142. package/src/Socket/Client/web-socket-client.ts +0 -57
  143. package/src/Socket/business.ts +0 -281
  144. package/src/Socket/chats.ts +0 -1030
  145. package/src/Socket/groups.ts +0 -356
  146. package/src/Socket/index.ts +0 -13
  147. package/src/Socket/messages-recv.ts +0 -985
  148. package/src/Socket/messages-send.ts +0 -871
  149. package/src/Socket/newsletter.ts +0 -282
  150. package/src/Socket/registration.ts +0 -250
  151. package/src/Socket/socket.ts +0 -777
  152. package/src/Store/index.ts +0 -3
  153. package/src/Store/make-cache-manager-store.ts +0 -100
  154. package/src/Store/make-in-memory-store.ts +0 -475
  155. package/src/Store/make-ordered-dictionary.ts +0 -86
  156. package/src/Store/object-repository.ts +0 -32
  157. package/src/Tests/test.app-state-sync.js +0 -204
  158. package/src/Tests/test.app-state-sync.ts +0 -207
  159. package/src/Tests/test.event-buffer.js +0 -270
  160. package/src/Tests/test.event-buffer.ts +0 -319
  161. package/src/Tests/test.key-store.js +0 -76
  162. package/src/Tests/test.key-store.ts +0 -92
  163. package/src/Tests/test.libsignal.js +0 -141
  164. package/src/Tests/test.libsignal.ts +0 -186
  165. package/src/Tests/test.media-download.js +0 -93
  166. package/src/Tests/test.media-download.ts +0 -76
  167. package/src/Tests/test.messages.js +0 -33
  168. package/src/Tests/test.messages.ts +0 -37
  169. package/src/Tests/utils.js +0 -34
  170. package/src/Tests/utils.ts +0 -36
  171. package/src/Types/Auth.ts +0 -113
  172. package/src/Types/Call.ts +0 -15
  173. package/src/Types/Chat.ts +0 -106
  174. package/src/Types/Events.ts +0 -93
  175. package/src/Types/GroupMetadata.ts +0 -53
  176. package/src/Types/Label.ts +0 -36
  177. package/src/Types/Message.ts +0 -288
  178. package/src/Types/Newsletter.ts +0 -98
  179. package/src/Types/Product.ts +0 -85
  180. package/src/Types/Signal.ts +0 -68
  181. package/src/Types/State.ts +0 -29
  182. package/src/Types/index.ts +0 -59
  183. package/src/Utils/auth-utils.ts +0 -222
  184. package/src/Utils/baileys-event-stream.js +0 -92
  185. package/src/Utils/baileys-event-stream.ts +0 -66
  186. package/src/Utils/business.ts +0 -275
  187. package/src/Utils/chat-utils.ts +0 -860
  188. package/src/Utils/crypto.ts +0 -131
  189. package/src/Utils/decode-wa-message.js +0 -211
  190. package/src/Utils/decode-wa-message.ts +0 -228
  191. package/src/Utils/event-buffer.ts +0 -613
  192. package/src/Utils/generics.ts +0 -434
  193. package/src/Utils/history.ts +0 -112
  194. package/src/Utils/index.ts +0 -17
  195. package/src/Utils/link-preview.ts +0 -122
  196. package/src/Utils/logger.ts +0 -3
  197. package/src/Utils/lt-hash.ts +0 -61
  198. package/src/Utils/make-mutex.ts +0 -44
  199. package/src/Utils/messages-media.ts +0 -847
  200. package/src/Utils/messages.ts +0 -956
  201. package/src/Utils/noise-handler.ts +0 -197
  202. package/src/Utils/process-message.ts +0 -414
  203. package/src/Utils/signal.ts +0 -177
  204. package/src/Utils/use-multi-file-auth-state.ts +0 -90
  205. package/src/Utils/validate-connection.ts +0 -238
  206. package/src/WABinary/constants.ts +0 -42
  207. package/src/WABinary/decode.ts +0 -265
  208. package/src/WABinary/encode.ts +0 -236
  209. package/src/WABinary/generic-utils.ts +0 -121
  210. package/src/WABinary/index.ts +0 -5
  211. package/src/WABinary/jid-utils.ts +0 -68
  212. package/src/WABinary/types.ts +0 -17
  213. package/src/WAM/BinaryInfo.ts +0 -12
  214. package/src/WAM/constants.ts +0 -15382
  215. package/src/WAM/encode.ts +0 -174
  216. package/src/WAM/index.ts +0 -3
  217. package/src/gifted +0 -1
  218. package/src/index.ts +0 -13
  219. /package/{src → lib}/Defaults/phonenumber-mcc.json +0 -0
  220. /package/{src → lib}/Socket/Client/abstract-socket-client.js +0 -0
  221. /package/{src → lib}/Store/index.js +0 -0
  222. /package/{src → lib}/Store/make-ordered-dictionary.js +0 -0
  223. /package/{src → lib}/Types/Auth.js +0 -0
  224. /package/{src → lib}/Types/Call.js +0 -0
  225. /package/{src → lib}/Types/Chat.js +0 -0
  226. /package/{src → lib}/Types/Contact.js +0 -0
  227. /package/{src → lib}/Types/Events.js +0 -0
  228. /package/{src → lib}/Types/GroupMetadata.js +0 -0
  229. /package/{src → lib}/Types/Label.js +0 -0
  230. /package/{src → lib}/Types/LabelAssociation.js +0 -0
  231. /package/{src → lib}/Types/Message.js +0 -0
  232. /package/{src → lib}/Types/Newsletter.js +0 -0
  233. /package/{src → lib}/Types/Product.js +0 -0
  234. /package/{src → lib}/Types/Signal.js +0 -0
  235. /package/{src → lib}/Types/Socket.js +0 -0
  236. /package/{src → lib}/Types/State.js +0 -0
  237. /package/{src/WABinary/types.js → lib/Types/USync.js} +0 -0
  238. /package/{src → lib}/Types/index.js +0 -0
  239. /package/{src → lib}/Utils/index.js +0 -0
  240. /package/{src → lib}/Utils/logger.js +0 -0
  241. /package/{src → lib}/Utils/lt-hash.js +0 -0
  242. /package/{src → lib}/Utils/noise-handler.js +0 -0
  243. /package/{src → lib}/WABinary/constants.js +0 -0
  244. /package/{src → lib}/WABinary/decode.js +0 -0
  245. /package/{src → lib}/WABinary/generic-utils.js +0 -0
  246. /package/{src → lib}/WABinary/index.js +0 -0
  247. /package/{src → lib}/WABinary/jid-utils.js +0 -0
  248. /package/{src → lib}/WAM/BinaryInfo.js +0 -0
  249. /package/{src → lib}/WAM/constants.js +0 -0
  250. /package/{src → lib}/WAM/encode.js +0 -0
  251. /package/{src → lib}/WAM/index.js +0 -0
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
@@ -28,7 +19,7 @@ const messages_send_1 = require("./messages-send");
28
19
  const makeMessagesRecvSocket = (config) => {
29
20
  const { logger, retryRequestDelayMs, maxMsgRetryCount, getMessage, shouldIgnoreJid } = config;
30
21
  const sock = (0, messages_send_1.makeMessagesSocket)(config);
31
- const { ev, authState, ws, processingMutex, signalRepository, query, upsertMessage, resyncAppState, onUnexpectedError, assertSessions, sendNode, relayMessage, sendReceipt, uploadPreKeys, getUSyncDevices, createParticipantNodes } = sock;
22
+ const { ev, authState, ws, processingMutex, signalRepository, query, upsertMessage, resyncAppState, onUnexpectedError, assertSessions, sendNode, relayMessage, sendReceipt, uploadPreKeys, getUSyncDevices, sendPeerDataOperationMessage, createParticipantNodes } = sock;
32
23
  /** this mutex ensures that each retryRequest will wait for the previous one to finish */
33
24
  const retryMutex = (0, make_mutex_1.makeMutex)();
34
25
  const msgRetryCache = config.msgRetryCounterCache || new node_cache_1.default({
@@ -39,32 +30,39 @@ const makeMessagesRecvSocket = (config) => {
39
30
  stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.CALL_OFFER, // 5 mins
40
31
  useClones: false
41
32
  });
33
+ const placeholderResendCache = config.placeholderResendCache || new node_cache_1.default({
34
+ stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
35
+ useClones: false
36
+ });
42
37
  let sendActiveReceipts = false;
43
- const sendMessageAck = (_a) => __awaiter(void 0, [_a], void 0, function* ({ tag, attrs, content }) {
38
+ const sendMessageAck = async ({ tag, attrs, content }, errorCode) => {
44
39
  const stanza = {
45
40
  tag: 'ack',
46
41
  attrs: {
47
42
  id: attrs.id,
48
43
  to: attrs.from,
49
- class: tag,
44
+ class: tag
50
45
  }
51
46
  };
47
+ if (!!errorCode) {
48
+ stanza.attrs.error = errorCode.toString();
49
+ }
52
50
  if (!!attrs.participant) {
53
51
  stanza.attrs.participant = attrs.participant;
54
52
  }
55
53
  if (!!attrs.recipient) {
56
54
  stanza.attrs.recipient = attrs.recipient;
57
55
  }
58
- if (!!attrs.type && (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable'))) {
56
+ if (!!attrs.type && (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
59
57
  stanza.attrs.type = attrs.type;
60
58
  }
61
59
  if (tag === 'message' && (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable')) {
62
60
  stanza.attrs.from = authState.creds.me.id;
63
61
  }
64
62
  logger.debug({ recv: { tag, attrs }, sent: stanza.attrs }, 'sent ack');
65
- yield sendNode(stanza);
66
- });
67
- const offerCall = (toJid_1, ...args_1) => __awaiter(void 0, [toJid_1, ...args_1], void 0, function* (toJid, isVideo = false) {
63
+ await sendNode(stanza);
64
+ };
65
+ const offerCall = async (toJid, isVideo = false) => {
68
66
  const callId = (0, crypto_1.randomBytes)(16).toString('hex').toUpperCase().substring(0, 64);
69
67
  const offerContent = [];
70
68
  offerContent.push({ tag: 'audio', attrs: { enc: 'opus', rate: '16000' }, content: undefined });
@@ -80,9 +78,9 @@ const makeMessagesRecvSocket = (config) => {
80
78
  offerContent.push({ tag: 'capability', attrs: { ver: '1' }, content: new Uint8Array([1, 4, 255, 131, 207, 4]) });
81
79
  offerContent.push({ tag: 'encopt', attrs: { keygen: '2' }, content: undefined });
82
80
  const encKey = (0, crypto_1.randomBytes)(32);
83
- const devices = (yield getUSyncDevices([toJid], true, false)).map(({ user, device }) => (0, WABinary_1.jidEncode)(user, 's.whatsapp.net', device));
84
- yield assertSessions(devices, true);
85
- const { nodes: destinations, shouldIncludeDeviceIdentity } = yield createParticipantNodes(devices, {
81
+ const devices = (await getUSyncDevices([toJid], true, false)).map(({ user, device }) => (0, WABinary_1.jidEncode)(user, 's.whatsapp.net', device));
82
+ await assertSessions(devices, true);
83
+ const { nodes: destinations, shouldIncludeDeviceIdentity } = await createParticipantNodes(devices, {
86
84
  call: {
87
85
  callKey: new Uint8Array(encKey)
88
86
  }
@@ -110,13 +108,13 @@ const makeMessagesRecvSocket = (config) => {
110
108
  content: offerContent,
111
109
  }],
112
110
  });
113
- yield query(stanza);
111
+ await query(stanza);
114
112
  return {
115
113
  id: callId,
116
114
  to: toJid
117
115
  };
118
- });
119
- const rejectCall = (callId, callFrom) => __awaiter(void 0, void 0, void 0, function* () {
116
+ };
117
+ const rejectCall = async (callId, callFrom) => {
120
118
  const stanza = ({
121
119
  tag: 'call',
122
120
  attrs: {
@@ -133,21 +131,29 @@ const makeMessagesRecvSocket = (config) => {
133
131
  content: undefined,
134
132
  }],
135
133
  });
136
- yield query(stanza);
137
- });
138
- const sendRetryRequest = (node_1, ...args_1) => __awaiter(void 0, [node_1, ...args_1], void 0, function* (node, forceIncludeKeys = false) {
139
- const msgId = node.attrs.id;
140
- let retryCount = msgRetryCache.get(msgId) || 0;
134
+ await query(stanza);
135
+ };
136
+ const sendRetryRequest = async (node, forceIncludeKeys = false) => {
137
+ const { fullMessage } = (0, Utils_1.decodeMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '');
138
+ const { key: msgKey } = fullMessage;
139
+ const msgId = msgKey.id;
140
+ const key = `${msgId}:${msgKey === null || msgKey === void 0 ? void 0 : msgKey.participant}`;
141
+ let retryCount = msgRetryCache.get(key) || 0;
141
142
  if (retryCount >= maxMsgRetryCount) {
142
143
  logger.debug({ retryCount, msgId }, 'reached retry limit, clearing');
143
- msgRetryCache.del(msgId);
144
+ msgRetryCache.del(key);
144
145
  return;
145
146
  }
146
147
  retryCount += 1;
147
- msgRetryCache.set(msgId, retryCount);
148
+ msgRetryCache.set(key, retryCount);
148
149
  const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds;
150
+ if (retryCount === 1) {
151
+ //request a resend via phone
152
+ const msgId = await requestPlaceholderResend(msgKey);
153
+ logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId}`);
154
+ }
149
155
  const deviceIdentity = (0, Utils_1.encodeSignedDeviceIdentity)(account, true);
150
- yield authState.keys.transaction(() => __awaiter(void 0, void 0, void 0, function* () {
156
+ await authState.keys.transaction(async () => {
151
157
  const receipt = {
152
158
  tag: 'receipt',
153
159
  attrs: {
@@ -179,7 +185,7 @@ const makeMessagesRecvSocket = (config) => {
179
185
  receipt.attrs.participant = node.attrs.participant;
180
186
  }
181
187
  if (retryCount > 1 || forceIncludeKeys) {
182
- const { update, preKeys } = yield (0, Utils_1.getNextPreKeys)(authState, 1);
188
+ const { update, preKeys } = await (0, Utils_1.getNextPreKeys)(authState, 1);
183
189
  const [keyId] = Object.keys(preKeys);
184
190
  const key = preKeys[+keyId];
185
191
  const content = receipt.content;
@@ -196,11 +202,11 @@ const makeMessagesRecvSocket = (config) => {
196
202
  });
197
203
  ev.emit('creds.update', update);
198
204
  }
199
- yield sendNode(receipt);
205
+ await sendNode(receipt);
200
206
  logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt');
201
- }));
202
- });
203
- const handleEncryptNotification = (node) => __awaiter(void 0, void 0, void 0, function* () {
207
+ });
208
+ };
209
+ const handleEncryptNotification = async (node) => {
204
210
  const from = node.attrs.from;
205
211
  if (from === WABinary_1.S_WHATSAPP_NET) {
206
212
  const countChild = (0, WABinary_1.getBinaryNodeChild)(node, 'count');
@@ -208,7 +214,7 @@ const makeMessagesRecvSocket = (config) => {
208
214
  const shouldUploadMorePreKeys = count < Defaults_1.MIN_PREKEY_COUNT;
209
215
  logger.debug({ count, shouldUploadMorePreKeys }, 'recv pre-key count');
210
216
  if (shouldUploadMorePreKeys) {
211
- yield uploadPreKeys();
217
+ await uploadPreKeys();
212
218
  }
213
219
  }
214
220
  else {
@@ -222,8 +228,10 @@ const makeMessagesRecvSocket = (config) => {
222
228
  logger.info({ node }, 'unknown encrypt notification');
223
229
  }
224
230
  }
225
- });
231
+ };
226
232
  const handleGroupNotification = (participant, child, msg) => {
233
+ var _a, _b, _c, _d;
234
+ 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;
227
235
  switch (child === null || child === void 0 ? void 0 : child.tag) {
228
236
  case 'create':
229
237
  const metadata = (0, groups_1.extractGroupMetadata)(child);
@@ -235,7 +243,10 @@ const makeMessagesRecvSocket = (config) => {
235
243
  name: metadata.subject,
236
244
  conversationTimestamp: metadata.creation,
237
245
  }]);
238
- ev.emit('groups.upsert', [Object.assign(Object.assign({}, metadata), { author: participant })]);
246
+ ev.emit('groups.upsert', [{
247
+ ...metadata,
248
+ author: participant
249
+ }]);
239
250
  break;
240
251
  case 'ephemeral':
241
252
  case 'not_ephemeral':
@@ -246,6 +257,11 @@ const makeMessagesRecvSocket = (config) => {
246
257
  }
247
258
  };
248
259
  break;
260
+ case 'modify':
261
+ const oldNumber = (0, WABinary_1.getBinaryNodeChildren)(child, 'participant').map(p => p.attrs.jid);
262
+ msg.messageStubParameters = oldNumber || [];
263
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER;
264
+ break;
249
265
  case 'promote':
250
266
  case 'demote':
251
267
  case 'remove':
@@ -267,6 +283,11 @@ const makeMessagesRecvSocket = (config) => {
267
283
  msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT;
268
284
  msg.messageStubParameters = [child.attrs.subject];
269
285
  break;
286
+ case 'description':
287
+ 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();
288
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_DESCRIPTION;
289
+ msg.messageStubParameters = description ? [description] : undefined;
290
+ break;
270
291
  case 'announcement':
271
292
  case 'not_announcement':
272
293
  msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE;
@@ -295,9 +316,18 @@ const makeMessagesRecvSocket = (config) => {
295
316
  msg.messageStubParameters = [approvalMode.attrs.state];
296
317
  }
297
318
  break;
319
+ case 'created_membership_requests':
320
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
321
+ msg.messageStubParameters = [participantJid, 'created', child.attrs.request_method];
322
+ break;
323
+ case 'revoked_membership_requests':
324
+ const isDenied = (0, WABinary_1.areJidsSameUser)(participantJid, participant);
325
+ msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
326
+ msg.messageStubParameters = [participantJid, isDenied ? 'revoked' : 'rejected'];
327
+ break;
298
328
  }
299
329
  };
300
- const processNotification = (node) => __awaiter(void 0, void 0, void 0, function* () {
330
+ const processNotification = async (node) => {
301
331
  var _a, _b, _c;
302
332
  const result = {};
303
333
  const [child] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
@@ -325,10 +355,7 @@ const makeMessagesRecvSocket = (config) => {
325
355
  ev.emit('messages.media-update', [event]);
326
356
  break;
327
357
  case 'encrypt':
328
- yield handleEncryptNotification(node);
329
- break;
330
- case 'newsletter':
331
- // TO DO
358
+ await handleEncryptNotification(node);
332
359
  break;
333
360
  case 'devices':
334
361
  const devices = (0, WABinary_1.getBinaryNodeChildren)(child, 'device');
@@ -341,14 +368,14 @@ const makeMessagesRecvSocket = (config) => {
341
368
  const update = (0, WABinary_1.getBinaryNodeChild)(node, 'collection');
342
369
  if (update) {
343
370
  const name = update.attrs.name;
344
- yield resyncAppState([name], false);
371
+ await resyncAppState([name], false);
345
372
  }
346
373
  break;
347
374
  case 'picture':
348
375
  const setPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'set');
349
376
  const delPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'delete');
350
377
  ev.emit('contacts.update', [{
351
- id: (0, WABinary_1.jidNormalizedUser)((_a = node === null || node === void 0 ? void 0 : node.attrs) === null || _a === void 0 ? void 0 : _a.jid) || ((_c = (_b = (setPicture || delPicture)) === null || _b === void 0 ? void 0 : _b.attrs) === null || _c === void 0 ? void 0 : _c.hash) || '',
378
+ id: (0, WABinary_1.jidNormalizedUser)((_a = node === null || node === void 0 ? void 0 : node.attrs) === null || _a === void 0 ? void 0 : _a.from) || ((_c = (_b = (setPicture || delPicture)) === null || _b === void 0 ? void 0 : _b.attrs) === null || _c === void 0 ? void 0 : _c.hash) || '',
352
379
  imgUrl: setPicture ? 'changed' : 'removed'
353
380
  }]);
354
381
  if ((0, WABinary_1.isJidGroup)(from)) {
@@ -358,7 +385,10 @@ const makeMessagesRecvSocket = (config) => {
358
385
  result.messageStubParameters = [setPicture.attrs.id];
359
386
  }
360
387
  result.participant = node === null || node === void 0 ? void 0 : node.attrs.author;
361
- result.key = Object.assign(Object.assign({}, result.key || {}), { participant: setPicture === null || setPicture === void 0 ? void 0 : setPicture.attrs.author });
388
+ result.key = {
389
+ ...result.key || {},
390
+ participant: setPicture === null || setPicture === void 0 ? void 0 : setPicture.attrs.author
391
+ };
362
392
  }
363
393
  break;
364
394
  case 'account_sync':
@@ -367,10 +397,13 @@ const makeMessagesRecvSocket = (config) => {
367
397
  const timestamp = +child.attrs.t;
368
398
  logger.info({ newDuration }, 'updated account disappearing mode');
369
399
  ev.emit('creds.update', {
370
- accountSettings: Object.assign(Object.assign({}, authState.creds.accountSettings), { defaultDisappearingMode: {
400
+ accountSettings: {
401
+ ...authState.creds.accountSettings,
402
+ defaultDisappearingMode: {
371
403
  ephemeralExpiration: newDuration,
372
404
  ephemeralSettingTimestamp: timestamp,
373
- } })
405
+ },
406
+ }
374
407
  });
375
408
  }
376
409
  else if (child.tag === 'blocklist') {
@@ -387,7 +420,7 @@ const makeMessagesRecvSocket = (config) => {
387
420
  const ref = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_ref'));
388
421
  const primaryIdentityPublicKey = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'primary_identity_pub'));
389
422
  const primaryEphemeralPublicKeyWrapped = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_wrapped_primary_ephemeral_pub'));
390
- const codePairingPublicKey = decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped);
423
+ const codePairingPublicKey = await decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped);
391
424
  const companionSharedKey = Utils_1.Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey);
392
425
  const random = (0, crypto_1.randomBytes)(32);
393
426
  const linkCodeSalt = (0, crypto_1.randomBytes)(32);
@@ -402,7 +435,7 @@ const makeMessagesRecvSocket = (config) => {
402
435
  const identitySharedKey = Utils_1.Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey);
403
436
  const identityPayload = Buffer.concat([companionSharedKey, identitySharedKey, random]);
404
437
  authState.creds.advSecretKey = (0, Utils_1.hkdf)(identityPayload, 32, { info: 'adv_secret' }).toString('base64');
405
- yield query({
438
+ await query({
406
439
  tag: 'iq',
407
440
  attrs: {
408
441
  to: WABinary_1.S_WHATSAPP_NET,
@@ -443,11 +476,11 @@ const makeMessagesRecvSocket = (config) => {
443
476
  if (Object.keys(result).length) {
444
477
  return result;
445
478
  }
446
- });
447
- function decipherLinkPublicKey(data) {
479
+ };
480
+ async function decipherLinkPublicKey(data) {
448
481
  const buffer = toRequiredBuffer(data);
449
482
  const salt = buffer.slice(0, 32);
450
- const secretKey = (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
483
+ const secretKey = await (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
451
484
  const iv = buffer.slice(32, 48);
452
485
  const payload = buffer.slice(48, 80);
453
486
  return (0, Utils_1.aesDecryptCTR)(payload, secretKey, iv);
@@ -468,22 +501,21 @@ const makeMessagesRecvSocket = (config) => {
468
501
  const newValue = (msgRetryCache.get(key) || 0) + 1;
469
502
  msgRetryCache.set(key, newValue);
470
503
  };
471
- const sendMessagesAgain = (key, ids, retryNode) => __awaiter(void 0, void 0, void 0, function* () {
504
+ const sendMessagesAgain = async (key, ids, retryNode) => {
472
505
  var _a;
473
- const msgs = yield Promise.all(ids.map(id => getMessage(Object.assign(Object.assign({}, key), { id }))));
506
+ const msgs = await Promise.all(ids.map(id => getMessage({ ...key, id })));
474
507
  const remoteJid = key.remoteJid;
475
508
  const participant = key.participant || remoteJid;
476
509
  // if it's the primary jid sending the request
477
510
  // just re-send the message to everyone
478
511
  // prevents the first message decryption failure
479
512
  const sendToAll = !((_a = (0, WABinary_1.jidDecode)(participant)) === null || _a === void 0 ? void 0 : _a.device);
480
- yield assertSessions([participant], true);
513
+ await assertSessions([participant], true);
481
514
  if ((0, WABinary_1.isJidGroup)(remoteJid)) {
482
- yield authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } });
515
+ await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } });
483
516
  }
484
517
  logger.debug({ participant, sendToAll }, 'forced new session for retry recp');
485
- for (let i = 0; i < msgs.length; i++) {
486
- const msg = msgs[i];
518
+ for (const [i, msg] of msgs.entries()) {
487
519
  if (msg) {
488
520
  updateSendMessageAgainCount(ids[i], participant);
489
521
  const msgRelayOpts = { messageId: ids[i] };
@@ -496,14 +528,14 @@ const makeMessagesRecvSocket = (config) => {
496
528
  count: +retryNode.attrs.count
497
529
  };
498
530
  }
499
- yield relayMessage(key.remoteJid, msg, msgRelayOpts);
531
+ await relayMessage(key.remoteJid, msg, msgRelayOpts);
500
532
  }
501
533
  else {
502
534
  logger.debug({ jid: key.remoteJid, id: ids[i] }, 'recv retry request, but message not available');
503
535
  }
504
536
  }
505
- });
506
- const handleReceipt = (node) => __awaiter(void 0, void 0, void 0, function* () {
537
+ };
538
+ const handleReceipt = async (node) => {
507
539
  var _a, _b;
508
540
  const { attrs, content } = node;
509
541
  const isLid = attrs.from.includes('lid');
@@ -518,7 +550,7 @@ const makeMessagesRecvSocket = (config) => {
518
550
  };
519
551
  if (shouldIgnoreJid(remoteJid) && remoteJid !== '@s.whatsapp.net') {
520
552
  logger.debug({ remoteJid }, 'ignoring receipt from jid');
521
- yield sendMessageAck(node);
553
+ await sendMessageAck(node);
522
554
  return;
523
555
  }
524
556
  const ids = [attrs.id];
@@ -526,147 +558,236 @@ const makeMessagesRecvSocket = (config) => {
526
558
  const items = (0, WABinary_1.getBinaryNodeChildren)(content[0], 'item');
527
559
  ids.push(...items.map(i => i.attrs.id));
528
560
  }
529
- yield Promise.all([
530
- processingMutex.mutex(() => __awaiter(void 0, void 0, void 0, function* () {
531
- const status = (0, Utils_1.getStatusFromReceiptType)(attrs.type);
532
- if (typeof status !== 'undefined' &&
533
- (
534
- // basically, we only want to know when a message from us has been delivered to/read by the other person
535
- // or another device of ours has read some messages
536
- status > WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK ||
537
- !isNodeFromMe)) {
538
- if ((0, WABinary_1.isJidGroup)(remoteJid)) {
539
- if (attrs.participant) {
540
- const updateKey = status === WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
541
- ev.emit('message-receipt.update', ids.map(id => ({
542
- key: Object.assign(Object.assign({}, key), { id }),
543
- receipt: {
544
- userJid: (0, WABinary_1.jidNormalizedUser)(attrs.participant),
545
- [updateKey]: +attrs.t
546
- }
561
+ try {
562
+ await Promise.all([
563
+ processingMutex.mutex(async () => {
564
+ const status = (0, Utils_1.getStatusFromReceiptType)(attrs.type);
565
+ if (typeof status !== 'undefined' &&
566
+ (
567
+ // basically, we only want to know when a message from us has been delivered to/read by the other person
568
+ // or another device of ours has read some messages
569
+ status > WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK ||
570
+ !isNodeFromMe)) {
571
+ if ((0, WABinary_1.isJidGroup)(remoteJid) || (0, WABinary_1.isJidStatusBroadcast)(remoteJid)) {
572
+ if (attrs.participant) {
573
+ const updateKey = status === WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
574
+ ev.emit('message-receipt.update', ids.map(id => ({
575
+ key: { ...key, id },
576
+ receipt: {
577
+ userJid: (0, WABinary_1.jidNormalizedUser)(attrs.participant),
578
+ [updateKey]: +attrs.t
579
+ }
580
+ })));
581
+ }
582
+ }
583
+ else {
584
+ ev.emit('messages.update', ids.map(id => ({
585
+ key: { ...key, id },
586
+ update: { status }
547
587
  })));
548
588
  }
549
589
  }
550
- else {
551
- ev.emit('messages.update', ids.map(id => ({
552
- key: Object.assign(Object.assign({}, key), { id }),
553
- update: { status }
554
- })));
555
- }
556
- }
557
- if (attrs.type === 'retry') {
558
- // correctly set who is asking for the retry
559
- key.participant = key.participant || attrs.from;
560
- const retryNode = (0, WABinary_1.getBinaryNodeChild)(node, 'retry');
561
- if (willSendMessageAgain(ids[0], key.participant)) {
562
- if (key.fromMe) {
563
- try {
564
- logger.debug({ attrs, key }, 'recv retry request');
565
- yield sendMessagesAgain(key, ids, retryNode);
590
+ if (attrs.type === 'retry') {
591
+ // correctly set who is asking for the retry
592
+ key.participant = key.participant || attrs.from;
593
+ const retryNode = (0, WABinary_1.getBinaryNodeChild)(node, 'retry');
594
+ if (willSendMessageAgain(ids[0], key.participant)) {
595
+ if (key.fromMe) {
596
+ try {
597
+ logger.debug({ attrs, key }, 'recv retry request');
598
+ await sendMessagesAgain(key, ids, retryNode);
599
+ }
600
+ catch (error) {
601
+ logger.error({ key, ids, trace: error.stack }, 'error in sending message again');
602
+ }
566
603
  }
567
- catch (error) {
568
- logger.error({ key, ids, trace: error.stack }, 'error in sending message again');
604
+ else {
605
+ logger.info({ attrs, key }, 'recv retry for not fromMe message');
569
606
  }
570
607
  }
571
608
  else {
572
- logger.info({ attrs, key }, 'recv retry for not fromMe message');
609
+ logger.info({ attrs, key }, 'will not send message again, as sent too many times');
573
610
  }
574
611
  }
575
- else {
576
- logger.info({ attrs, key }, 'will not send message again, as sent too many times');
577
- }
578
- }
579
- })),
580
- sendMessageAck(node)
581
- ]);
582
- });
583
- const handleNotification = (node) => __awaiter(void 0, void 0, void 0, function* () {
612
+ })
613
+ ]);
614
+ }
615
+ finally {
616
+ await sendMessageAck(node);
617
+ }
618
+ };
619
+ const handleNotification = async (node) => {
584
620
  const remoteJid = node.attrs.from;
585
621
  if (shouldIgnoreJid(remoteJid) && remoteJid !== '@s.whatsapp.net') {
586
622
  logger.debug({ remoteJid, id: node.attrs.id }, 'ignored notification');
587
- yield sendMessageAck(node);
623
+ await sendMessageAck(node);
588
624
  return;
589
625
  }
590
- yield Promise.all([
591
- processingMutex.mutex(() => __awaiter(void 0, void 0, void 0, function* () {
592
- var _a;
593
- const msg = yield processNotification(node);
594
- if (msg) {
595
- const fromMe = (0, WABinary_1.areJidsSameUser)(node.attrs.participant || remoteJid, authState.creds.me.id);
596
- msg.key = Object.assign({ remoteJid,
597
- fromMe, participant: node.attrs.participant, id: node.attrs.id }, (msg.key || {}));
598
- (_a = msg.participant) !== null && _a !== void 0 ? _a : (msg.participant = node.attrs.participant);
599
- msg.messageTimestamp = +node.attrs.t;
600
- const fullMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
601
- yield upsertMessage(fullMsg, 'append');
602
- }
603
- })),
604
- sendMessageAck(node)
605
- ]);
606
- });
607
- const handleMessage = (node) => __awaiter(void 0, void 0, void 0, function* () {
608
- var _a, _b;
626
+ try {
627
+ await Promise.all([
628
+ processingMutex.mutex(async () => {
629
+ var _a;
630
+ const msg = await processNotification(node);
631
+ if (msg) {
632
+ const fromMe = (0, WABinary_1.areJidsSameUser)(node.attrs.participant || remoteJid, authState.creds.me.id);
633
+ msg.key = {
634
+ remoteJid,
635
+ fromMe,
636
+ participant: node.attrs.participant,
637
+ id: node.attrs.id,
638
+ ...(msg.key || {})
639
+ };
640
+ (_a = msg.participant) !== null && _a !== void 0 ? _a : (msg.participant = node.attrs.participant);
641
+ msg.messageTimestamp = +node.attrs.t;
642
+ const fullMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
643
+ await upsertMessage(fullMsg, 'append');
644
+ }
645
+ })
646
+ ]);
647
+ }
648
+ finally {
649
+ await sendMessageAck(node);
650
+ }
651
+ };
652
+ const handleMessage = async (node) => {
653
+ var _a, _b, _c;
609
654
  if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !== '@s.whatsapp.net') {
610
655
  logger.debug({ key: node.attrs.key }, 'ignored message');
611
- yield sendMessageAck(node);
656
+ await sendMessageAck(node);
612
657
  return;
613
658
  }
614
- const { fullMessage: msg, category, author, decrypt } = (0, Utils_1.decryptMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
615
- if (((_b = (_a = msg.message) === null || _a === void 0 ? void 0 : _a.protocolMessage) === null || _b === void 0 ? void 0 : _b.type) === WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER) {
616
- if (node.attrs.sender_pn) {
617
- ev.emit('chats.phoneNumberShare', { lid: node.attrs.from, jid: node.attrs.sender_pn });
659
+ let response;
660
+ if ((0, WABinary_1.getBinaryNodeChild)(node, 'unavailable') && !(0, WABinary_1.getBinaryNodeChild)(node, 'enc')) {
661
+ await sendMessageAck(node);
662
+ const { key } = (0, Utils_1.decodeMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '').fullMessage;
663
+ response = await requestPlaceholderResend(key);
664
+ if (response === 'RESOLVED') {
665
+ return;
618
666
  }
667
+ logger.debug('received unavailable message, acked and requested resend from phone');
619
668
  }
620
- yield Promise.all([
621
- processingMutex.mutex(() => __awaiter(void 0, void 0, void 0, function* () {
622
- yield decrypt();
623
- // message failed to decrypt
624
- if (msg.messageStubType === WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT) {
625
- retryMutex.mutex(() => __awaiter(void 0, void 0, void 0, function* () {
626
- if (ws.isOpen) {
627
- const encNode = (0, WABinary_1.getBinaryNodeChild)(node, 'enc');
628
- yield sendRetryRequest(node, !encNode);
629
- if (retryRequestDelayMs) {
630
- yield (0, Utils_1.delay)(retryRequestDelayMs);
669
+ else {
670
+ if (placeholderResendCache.get(node.attrs.id)) {
671
+ placeholderResendCache.del(node.attrs.id);
672
+ }
673
+ }
674
+ const { fullMessage: msg, category, author, decrypt } = (0, Utils_1.decryptMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
675
+ 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) {
676
+ msg.messageStubParameters = [Utils_1.NO_MESSAGE_FOUND_ERROR_TEXT, response];
677
+ }
678
+ 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) {
679
+ ev.emit('chats.phoneNumberShare', { lid: node.attrs.from, jid: node.attrs.sender_pn });
680
+ }
681
+ try {
682
+ await Promise.all([
683
+ processingMutex.mutex(async () => {
684
+ var _a;
685
+ await decrypt();
686
+ // message failed to decrypt
687
+ if (msg.messageStubType === WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT) {
688
+ 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) {
689
+ return sendMessageAck(node, Utils_1.NACK_REASONS.ParsingError);
690
+ }
691
+ retryMutex.mutex(async () => {
692
+ if (ws.isOpen) {
693
+ if ((0, WABinary_1.getBinaryNodeChild)(node, 'unavailable')) {
694
+ return;
695
+ }
696
+ const encNode = (0, WABinary_1.getBinaryNodeChild)(node, 'enc');
697
+ await sendRetryRequest(node, !encNode);
698
+ if (retryRequestDelayMs) {
699
+ await (0, Utils_1.delay)(retryRequestDelayMs);
700
+ }
701
+ }
702
+ else {
703
+ logger.debug({ node }, 'connection closed, ignoring retry req');
704
+ }
705
+ });
706
+ }
707
+ else {
708
+ // no type in the receipt => message delivered
709
+ let type = undefined;
710
+ let participant = msg.key.participant;
711
+ if (category === 'peer') { // special peer message
712
+ type = 'peer_msg';
713
+ }
714
+ else if (msg.key.fromMe) { // message was sent by us from a different device
715
+ type = 'sender';
716
+ // need to specially handle this case
717
+ if ((0, WABinary_1.isJidUser)(msg.key.remoteJid)) {
718
+ participant = author;
631
719
  }
632
720
  }
633
- else {
634
- logger.debug({ node }, 'connection closed, ignoring retry req');
721
+ else if (!sendActiveReceipts) {
722
+ type = 'inactive';
635
723
  }
636
- }));
637
- }
638
- else {
639
- // no type in the receipt => message delivered
640
- let type = undefined;
641
- let participant = msg.key.participant;
642
- if (category === 'peer') { // special peer message
643
- type = 'peer_msg';
644
- }
645
- else if (msg.key.fromMe) { // message was sent by us from a different device
646
- type = 'sender';
647
- // need to specially handle this case
648
- if ((0, WABinary_1.isJidUser)(msg.key.remoteJid)) {
649
- participant = author;
724
+ await sendReceipt(msg.key.remoteJid, participant, [msg.key.id], type);
725
+ // send ack for history message
726
+ const isAnyHistoryMsg = (0, Utils_1.getHistoryMsg)(msg.message);
727
+ if (isAnyHistoryMsg) {
728
+ const jid = (0, WABinary_1.jidNormalizedUser)(msg.key.remoteJid);
729
+ await sendReceipt(jid, undefined, [msg.key.id], 'hist_sync');
650
730
  }
651
731
  }
652
- else if (!sendActiveReceipts) {
653
- type = 'inactive';
654
- }
655
- yield sendReceipt(msg.key.remoteJid, participant, [msg.key.id], type);
656
- // send ack for history message
657
- const isAnyHistoryMsg = (0, Utils_1.getHistoryMsg)(msg.message);
658
- if (isAnyHistoryMsg) {
659
- const jid = (0, WABinary_1.jidNormalizedUser)(msg.key.remoteJid);
660
- yield sendReceipt(jid, undefined, [msg.key.id], 'hist_sync');
661
- }
662
- }
663
- (0, Utils_2.cleanMessage)(msg, authState.creds.me.id);
664
- yield upsertMessage(msg, node.attrs.offline ? 'append' : 'notify');
665
- })),
666
- sendMessageAck(node)
667
- ]);
668
- });
669
- const handleCall = (node) => __awaiter(void 0, void 0, void 0, function* () {
732
+ (0, Utils_2.cleanMessage)(msg, authState.creds.me.id);
733
+ await sendMessageAck(node);
734
+ await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify');
735
+ })
736
+ ]);
737
+ }
738
+ catch (error) {
739
+ logger.error({ error, node }, 'error in handling message');
740
+ }
741
+ };
742
+ const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
743
+ var _a;
744
+ if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
745
+ throw new boom_1.Boom('Not authenticated');
746
+ }
747
+ const pdoMessage = {
748
+ historySyncOnDemandRequest: {
749
+ chatJid: oldestMsgKey.remoteJid,
750
+ oldestMsgFromMe: oldestMsgKey.fromMe,
751
+ oldestMsgId: oldestMsgKey.id,
752
+ oldestMsgTimestampMs: oldestMsgTimestamp,
753
+ onDemandMsgCount: count
754
+ },
755
+ peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
756
+ };
757
+ return sendPeerDataOperationMessage(pdoMessage);
758
+ };
759
+ const requestPlaceholderResend = async (messageKey) => {
760
+ var _a;
761
+ if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
762
+ throw new boom_1.Boom('Not authenticated');
763
+ }
764
+ if (placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
765
+ logger.debug('already requested resend', { messageKey });
766
+ return;
767
+ }
768
+ else {
769
+ placeholderResendCache.set(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id, true);
770
+ }
771
+ await (0, Utils_1.delay)(5000);
772
+ if (!placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
773
+ logger.debug('message received while resend requested', { messageKey });
774
+ return 'RESOLVED';
775
+ }
776
+ const pdoMessage = {
777
+ placeholderMessageResendRequest: [{
778
+ messageKey
779
+ }],
780
+ peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
781
+ };
782
+ setTimeout(() => {
783
+ if (placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
784
+ logger.debug('PDO message without response after 15 seconds. Phone possibly offline', { messageKey });
785
+ placeholderResendCache.del(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id);
786
+ }
787
+ }, 15000);
788
+ return sendPeerDataOperationMessage(pdoMessage);
789
+ };
790
+ const handleCall = async (node) => {
670
791
  const { attrs } = node;
671
792
  const [infoChild] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
672
793
  const callId = infoChild.attrs['call-id'];
@@ -693,27 +814,27 @@ const makeMessagesRecvSocket = (config) => {
693
814
  call.isGroup = existingCall.isGroup;
694
815
  }
695
816
  // delete data once call has ended
696
- if (status === 'reject' || status === 'accept' || status === 'timeout') {
817
+ if (status === 'reject' || status === 'accept' || status === 'timeout' || status === 'terminate') {
697
818
  callOfferCache.del(call.id);
698
819
  }
699
820
  ev.emit('call', [call]);
700
- yield sendMessageAck(node);
701
- });
702
- const handleBadAck = (_a) => __awaiter(void 0, [_a], void 0, function* ({ attrs }) {
821
+ await sendMessageAck(node);
822
+ };
823
+ const handleBadAck = async ({ attrs }) => {
703
824
  const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id };
704
- // current hypothesis is that if pash is sent in the ack
705
- // it means -- the message hasn't reached all devices yet
706
- // we'll retry sending the message here
707
- if (attrs.phash) {
708
- logger.info({ attrs }, 'received phash in ack, resending message...');
709
- const msg = yield getMessage(key);
710
- if (msg) {
711
- yield relayMessage(key.remoteJid, msg, { messageId: key.id, useUserDevicesCache: false });
712
- }
713
- else {
714
- logger.warn({ attrs }, 'could not send message again, as it was not found');
715
- }
716
- }
825
+ // WARNING: REFRAIN FROM ENABLING THIS FOR NOW. IT WILL CAUSE A LOOP
826
+ // // current hypothesis is that if pash is sent in the ack
827
+ // // it means -- the message hasn't reached all devices yet
828
+ // // we'll retry sending the message here
829
+ // if(attrs.phash) {
830
+ // logger.info({ attrs }, 'received phash in ack, resending message...')
831
+ // const msg = await getMessage(key)
832
+ // if(msg) {
833
+ // await relayMessage(key.remoteJid!, msg, { messageId: key.id!, useUserDevicesCache: false })
834
+ // } else {
835
+ // logger.warn({ attrs }, 'could not send message again, as it was not found')
836
+ // }
837
+ // }
717
838
  // error in acknowledgement,
718
839
  // device could not display the message
719
840
  if (attrs.error) {
@@ -730,31 +851,72 @@ const makeMessagesRecvSocket = (config) => {
730
851
  }
731
852
  ]);
732
853
  }
733
- });
854
+ };
734
855
  /// processes a node with the given function
735
856
  /// and adds the task to the existing buffer if we're buffering events
736
- const processNodeWithBuffer = (node, identifier, exec) => __awaiter(void 0, void 0, void 0, function* () {
857
+ const processNodeWithBuffer = async (node, identifier, exec) => {
737
858
  ev.buffer();
738
- yield execTask();
859
+ await execTask();
739
860
  ev.flush();
740
861
  function execTask() {
741
- return exec(node)
862
+ return exec(node, false)
742
863
  .catch(err => onUnexpectedError(err, identifier));
743
864
  }
744
- });
865
+ };
866
+ const makeOfflineNodeProcessor = () => {
867
+ const nodeProcessorMap = new Map([
868
+ ['message', handleMessage],
869
+ ['call', handleCall],
870
+ ['receipt', handleReceipt],
871
+ ['notification', handleNotification]
872
+ ]);
873
+ const nodes = [];
874
+ let isProcessing = false;
875
+ const enqueue = (type, node) => {
876
+ nodes.push({ type, node });
877
+ if (isProcessing) {
878
+ return;
879
+ }
880
+ isProcessing = true;
881
+ const promise = async () => {
882
+ while (nodes.length && ws.isOpen) {
883
+ const { type, node } = nodes.shift();
884
+ const nodeProcessor = nodeProcessorMap.get(type);
885
+ if (!nodeProcessor) {
886
+ onUnexpectedError(new Error(`unknown offline node type: ${type}`), 'processing offline node');
887
+ continue;
888
+ }
889
+ await nodeProcessor(node);
890
+ }
891
+ isProcessing = false;
892
+ };
893
+ promise().catch(error => onUnexpectedError(error, 'processing offline nodes'));
894
+ };
895
+ return { enqueue };
896
+ };
897
+ const offlineNodeProcessor = makeOfflineNodeProcessor();
898
+ const processNode = (type, node, identifier, exec) => {
899
+ const isOffline = !!node.attrs.offline;
900
+ if (isOffline) {
901
+ offlineNodeProcessor.enqueue(type, node);
902
+ }
903
+ else {
904
+ processNodeWithBuffer(node, identifier, exec);
905
+ }
906
+ };
745
907
  // recv a message
746
908
  ws.on('CB:message', (node) => {
747
- processNodeWithBuffer(node, 'processing message', handleMessage);
909
+ processNode('message', node, 'processing message', handleMessage);
910
+ });
911
+ ws.on('CB:call', async (node) => {
912
+ processNode('call', node, 'handling call', handleCall);
748
913
  });
749
- ws.on('CB:call', (node) => __awaiter(void 0, void 0, void 0, function* () {
750
- processNodeWithBuffer(node, 'handling call', handleCall);
751
- }));
752
914
  ws.on('CB:receipt', node => {
753
- processNodeWithBuffer(node, 'handling receipt', handleReceipt);
915
+ processNode('receipt', node, 'handling receipt', handleReceipt);
916
+ });
917
+ ws.on('CB:notification', async (node) => {
918
+ processNode('notification', node, 'handling notification', handleNotification);
754
919
  });
755
- ws.on('CB:notification', (node) => __awaiter(void 0, void 0, void 0, function* () {
756
- processNodeWithBuffer(node, 'handling notification', handleNotification);
757
- }));
758
920
  ws.on('CB:ack,class:message', (node) => {
759
921
  handleBadAck(node)
760
922
  .catch(error => onUnexpectedError(error, 'handling bad ack'));
@@ -791,9 +953,14 @@ const makeMessagesRecvSocket = (config) => {
791
953
  logger.trace(`sendActiveReceipts set to "${sendActiveReceipts}"`);
792
954
  }
793
955
  });
794
- return Object.assign(Object.assign({}, sock), { sendMessageAck,
956
+ return {
957
+ ...sock,
958
+ sendMessageAck,
795
959
  sendRetryRequest,
796
960
  offerCall,
797
- rejectCall });
961
+ rejectCall,
962
+ fetchMessageHistory,
963
+ requestPlaceholderResend,
964
+ };
798
965
  };
799
966
  exports.makeMessagesRecvSocket = makeMessagesRecvSocket;