@pontalabs/baileys 1.0.10 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +96 -85
  2. package/lib/Defaults/connection.js +39 -0
  3. package/lib/Defaults/constants.js +50 -0
  4. package/lib/Defaults/history.js +13 -0
  5. package/lib/Defaults/index.js +36 -151
  6. package/lib/Defaults/media.js +43 -0
  7. package/lib/Defaults/phonenumber-mcc.json +221 -221
  8. package/lib/Defaults/prefix.js +12 -0
  9. package/lib/Defaults/vialeys-version.json +7 -0
  10. package/lib/Signal/Group/ciphertext-message.js +10 -15
  11. package/lib/Signal/Group/group-session-builder.js +34 -60
  12. package/lib/Signal/Group/group_cipher.js +69 -76
  13. package/lib/Signal/Group/index.js +41 -60
  14. package/lib/Signal/Group/keyhelper.js +12 -57
  15. package/lib/Signal/Group/sender-chain-key.js +20 -33
  16. package/lib/Signal/Group/sender-key-distribution-message.js +43 -48
  17. package/lib/Signal/Group/sender-key-message.js +58 -53
  18. package/lib/Signal/Group/sender-key-name.js +21 -31
  19. package/lib/Signal/Group/sender-key-record.js +21 -34
  20. package/lib/Signal/Group/sender-key-state.js +59 -106
  21. package/lib/Signal/Group/sender-message-key.js +16 -21
  22. package/lib/Signal/libsignal.js +282 -203
  23. package/lib/Signal/lid-mapping.js +164 -184
  24. package/lib/Socket/Client/index.js +31 -22
  25. package/lib/Socket/Client/types.js +9 -15
  26. package/lib/Socket/Client/websocket.js +42 -37
  27. package/lib/Socket/business.js +212 -336
  28. package/lib/Socket/chats.js +696 -940
  29. package/lib/Socket/community.js +454 -369
  30. package/lib/Socket/groups.js +278 -280
  31. package/lib/Socket/index.js +9 -21
  32. package/lib/Socket/messages-recv.js +1027 -1570
  33. package/lib/Socket/messages-send.js +1180 -1136
  34. package/lib/Socket/mex.js +59 -0
  35. package/lib/Socket/newsletter.js +193 -251
  36. package/lib/Socket/socket.js +758 -898
  37. package/lib/Store/index.js +35 -24
  38. package/lib/Store/make-cache-manager-store.js +53 -66
  39. package/lib/Store/make-in-memory-store.js +319 -325
  40. package/lib/Store/make-ordered-dictionary.js +49 -57
  41. package/lib/Store/object-repository.js +10 -15
  42. package/lib/Types/Auth.js +2 -3
  43. package/lib/Types/Bussines.js +2 -3
  44. package/lib/Types/Call.js +2 -3
  45. package/lib/Types/Chat.js +10 -9
  46. package/lib/Types/Contact.js +2 -3
  47. package/lib/Types/Events.js +2 -3
  48. package/lib/Types/GroupMetadata.js +2 -3
  49. package/lib/Types/Label.js +6 -12
  50. package/lib/Types/LabelAssociation.js +4 -13
  51. package/lib/Types/Message.js +10 -18
  52. package/lib/Types/MexUpdates.js +15 -18
  53. package/lib/Types/Newsletter.js +26 -34
  54. package/lib/Types/Product.js +2 -3
  55. package/lib/Types/Signal.js +2 -3
  56. package/lib/Types/Socket.js +2 -3
  57. package/lib/Types/State.js +8 -13
  58. package/lib/Types/USync.js +2 -3
  59. package/lib/Types/index.js +49 -40
  60. package/lib/Utils/auth-utils.js +190 -495
  61. package/lib/Utils/browser-utils.js +29 -0
  62. package/lib/Utils/business.js +177 -199
  63. package/lib/Utils/chat-utils.js +711 -624
  64. package/lib/Utils/crypto.js +116 -161
  65. package/lib/Utils/decode-wa-message.js +225 -321
  66. package/lib/Utils/event-buffer.js +363 -405
  67. package/lib/Utils/generics.js +318 -472
  68. package/lib/Utils/history.js +72 -76
  69. package/lib/Utils/index.js +49 -41
  70. package/lib/Utils/link-preview.js +59 -103
  71. package/lib/Utils/logger.js +4 -7
  72. package/lib/Utils/lt-hash.js +29 -42
  73. package/lib/Utils/make-mutex.js +26 -42
  74. package/lib/Utils/message-retry-manager.js +134 -160
  75. package/lib/Utils/messages-media.js +665 -731
  76. package/lib/Utils/messages.js +518 -1
  77. package/lib/Utils/noise-handler.js +127 -125
  78. package/lib/Utils/pre-key-manager.js +86 -0
  79. package/lib/Utils/process-message.js +739 -351
  80. package/lib/Utils/signal.js +146 -129
  81. package/lib/Utils/use-multi-file-auth-state.js +68 -135
  82. package/lib/Utils/validate-connection.js +183 -142
  83. package/lib/Utils/vialeys-event-stream.js +41 -0
  84. package/lib/WABinary/constants.js +1281 -1289
  85. package/lib/WABinary/decode.js +145 -200
  86. package/lib/WABinary/encode.js +149 -202
  87. package/lib/WABinary/generic-utils.js +79 -97
  88. package/lib/WABinary/index.js +36 -25
  89. package/lib/WABinary/jid-utils.js +91 -123
  90. package/lib/WABinary/types.js +2 -3
  91. package/lib/WAM/BinaryInfo.js +8 -13
  92. package/lib/WAM/constants.js +16584 -11464
  93. package/lib/WAM/encode.js +117 -133
  94. package/lib/WAM/index.js +34 -23
  95. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +62 -69
  96. package/lib/WAUSync/Protocols/USyncContactProtocol.js +11 -25
  97. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +32 -44
  98. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +13 -23
  99. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +24 -38
  100. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +17 -31
  101. package/lib/WAUSync/Protocols/index.js +37 -26
  102. package/lib/WAUSync/USyncQuery.js +66 -66
  103. package/lib/WAUSync/USyncUser.js +13 -18
  104. package/lib/WAUSync/index.js +34 -23
  105. package/lib/index.js +95 -28
  106. package/package.json +4 -3
  107. package/lib/Defaults/baileys-version.json +0 -3
  108. package/lib/Signal/Group/queue-job.d.ts +0 -1
  109. package/lib/Signal/Group/queue-job.js +0 -57
  110. package/lib/Socket/usync.d.ts +0 -37
  111. package/lib/Socket/usync.js +0 -83
  112. package/lib/Utils/baileys-event-stream.d.ts +0 -18
  113. package/lib/Utils/baileys-event-stream.js +0 -70
  114. package/lib/Utils/signal-housekeeping.d.ts +0 -19
  115. package/lib/Utils/signal-housekeeping.js +0 -73
  116. package/lib/Utils/use-mongo-file-auth-state.d.ts +0 -6
  117. package/lib/Utils/use-mongo-file-auth-state.js +0 -84
  118. package/lib/Utils/use-single-file-auth-state.d.ts +0 -13
  119. package/lib/Utils/use-single-file-auth-state.js +0 -80
@@ -1,426 +1,814 @@
1
- "use strict"
2
-
3
- Object.defineProperty(exports, "__esModule", { value: true })
4
-
5
- const WAProto_1 = require("../../WAProto")
6
- const Types_1 = require("../Types")
7
- const messages_1 = require("../Utils/messages")
8
- const WABinary_1 = require("../WABinary")
9
- const crypto_1 = require("./crypto")
10
- const generics_1 = require("./generics")
11
- const history_1 = require("./history")
12
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const { proto: proto } = require("../../WAProto");
4
+ const { WAMessageStubType: WAMessageStubType } = require("../Types");
5
+ const {
6
+ getDevice: getDevice,
7
+ getContentType: getContentType,
8
+ normalizeMessageContent: normalizeMessageContent,
9
+ } = require("../Utils");
10
+ const {
11
+ areJidsSameUser: areJidsSameUser,
12
+ isHostedLidUser: isHostedLidUser,
13
+ isHostedPnUser: isHostedPnUser,
14
+ isJidBroadcast: isJidBroadcast,
15
+ isJidStatusBroadcast: isJidStatusBroadcast,
16
+ isLidUser: isLidUser,
17
+ jidDecode: jidDecode,
18
+ jidEncode: jidEncode,
19
+ jidNormalizedUser: jidNormalizedUser,
20
+ } = require("../WABinary");
21
+ const { aesDecryptGCM: aesDecryptGCM, hmacSign: hmacSign } = require("./crypto");
22
+ const { getKeyAuthor: getKeyAuthor, toNumber: toNumber } = require("./generics");
23
+ const {
24
+ downloadAndProcessHistorySyncNotification: downloadAndProcessHistorySyncNotification,
25
+ } = require("./history");
13
26
  const REAL_MSG_STUB_TYPES = new Set([
14
- Types_1.WAMessageStubType.CALL_MISSED_GROUP_VIDEO,
15
- Types_1.WAMessageStubType.CALL_MISSED_GROUP_VOICE,
16
- Types_1.WAMessageStubType.CALL_MISSED_VIDEO,
17
- Types_1.WAMessageStubType.CALL_MISSED_VOICE
18
- ])
19
-
20
- const REAL_MSG_REQ_ME_STUB_TYPES = new Set([
21
- Types_1.WAMessageStubType.GROUP_PARTICIPANT_ADD
22
- ])
23
-
24
- /** Cleans a received message to further processing */
25
- const cleanMessage = (message, meId) => {
26
- // ensure remoteJid and participant doesn't have device or agent in it
27
- message.key.remoteJid = WABinary_1.jidNormalizedUser(message.key.remoteJid)
28
- message.key.participant = message.key.participant ? WABinary_1.jidNormalizedUser(message.key.participant) : undefined
29
- const content = messages_1.normalizeMessageContent(message.message)
30
- // if the message has a reaction, ensure fromMe & remoteJid are from our perspective
27
+ WAMessageStubType.CALL_MISSED_GROUP_VIDEO,
28
+ WAMessageStubType.CALL_MISSED_GROUP_VOICE,
29
+ WAMessageStubType.CALL_MISSED_VIDEO,
30
+ WAMessageStubType.CALL_MISSED_VOICE,
31
+ ]);
32
+ const REAL_MSG_REQ_ME_STUB_TYPES = new Set([WAMessageStubType.GROUP_PARTICIPANT_ADD]);
33
+ const cleanMessage = (message, meId, meLid) => {
34
+ if (isHostedPnUser(message.key.remoteJid) || isHostedLidUser(message.key.remoteJid)) {
35
+ message.key.remoteJid = jidEncode(
36
+ jidDecode(message.key?.remoteJid)?.user,
37
+ isHostedPnUser(message.key.remoteJid) ? "s.whatsapp.net" : "lid"
38
+ );
39
+ } else {
40
+ message.key.remoteJid = jidNormalizedUser(message.key.remoteJid);
41
+ }
42
+ if (isHostedPnUser(message.key.participant) || isHostedLidUser(message.key.participant)) {
43
+ message.key.participant = jidEncode(
44
+ jidDecode(message.key.participant)?.user,
45
+ isHostedPnUser(message.key.participant) ? "s.whatsapp.net" : "lid"
46
+ );
47
+ } else {
48
+ message.key.participant = jidNormalizedUser(message.key.participant);
49
+ }
50
+ const content = normalizeMessageContent(message.message);
31
51
  if (content?.reactionMessage) {
32
- normaliseKey(content.reactionMessage.key)
52
+ normaliseKey(content.reactionMessage.key);
33
53
  }
34
54
  if (content?.pollUpdateMessage) {
35
- normaliseKey(content.pollUpdateMessage.pollCreationMessageKey)
55
+ normaliseKey(content.pollUpdateMessage.pollCreationMessageKey);
36
56
  }
37
57
  function normaliseKey(msgKey) {
38
- // if the reaction is from another user
39
- // we've to correctly map the key to this user's perspective
40
58
  if (!message.key.fromMe) {
41
- // if the sender believed the message being reacted to is not from them
42
- // we've to correct the key to be from them, or some other participant
43
59
  msgKey.fromMe = !msgKey.fromMe
44
- ? WABinary_1.areJidsSameUser(msgKey.participant || msgKey.remoteJid, meId)
45
- // if the message being reacted to, was from them
46
- // fromMe automatically becomes false
47
- : false
48
- // set the remoteJid to being the same as the chat the message came from
49
- msgKey.remoteJid = message.key.remoteJid
50
- // set participant of the message
51
- msgKey.participant = msgKey.participant || message.key.participant
60
+ ? areJidsSameUser(msgKey.participant || msgKey.remoteJid, meId) ||
61
+ areJidsSameUser(msgKey.participant || msgKey.remoteJid, meLid)
62
+ : false;
63
+ msgKey.remoteJid = message.key.remoteJid;
64
+ msgKey.participant = msgKey.participant || message.key.participant;
52
65
  }
53
66
  }
54
- }
55
-
56
- const isRealMessage = (message, meId) => {
57
- const normalizedContent = messages_1.normalizeMessageContent(message.message)
58
- const hasSomeContent = !!messages_1.getContentType(normalizedContent)
67
+ };
68
+ const isRealMessage = (message) => {
69
+ const normalizedContent = normalizeMessageContent(message.message);
70
+ const hasSomeContent = !!getContentType(normalizedContent);
59
71
  return (
60
- !!normalizedContent ||
61
- REAL_MSG_STUB_TYPES.has(message.messageStubType) ||
62
- (
63
- REAL_MSG_REQ_ME_STUB_TYPES.has(message.messageStubType) &&
64
- message.messageStubParameters?.some(p => WABinary_1.areJidsSameUser(meId, p))
65
- )
66
- ) &&
67
- hasSomeContent &&
68
- !normalizedContent?.protocolMessage &&
69
- !normalizedContent?.reactionMessage &&
70
- !normalizedContent?.pollUpdateMessage
71
- }
72
-
73
- const shouldIncrementChatUnread = (message) => (!message.key.fromMe && !message.messageStubType)
74
-
75
- /**
76
- * Get the ID of the chat from the given key.
77
- * Typically -- that'll be the remoteJid, but for broadcasts, it'll be the participant
78
- */
79
- const getChatId = ({ remoteJid, participant, fromMe }) => {
80
- if (WABinary_1.isJidBroadcast(remoteJid)
81
- && !WABinary_1.isJidStatusBroadcast(remoteJid)
82
- && !fromMe) {
83
- return participant
72
+ (!!normalizedContent ||
73
+ REAL_MSG_STUB_TYPES.has(message.messageStubType) ||
74
+ REAL_MSG_REQ_ME_STUB_TYPES.has(message.messageStubType)) &&
75
+ hasSomeContent &&
76
+ !normalizedContent?.protocolMessage &&
77
+ !normalizedContent?.reactionMessage &&
78
+ !normalizedContent?.pollUpdateMessage
79
+ );
80
+ };
81
+ const shouldIncrementChatUnread = (message) => !message.key.fromMe && !message.messageStubType;
82
+ const getChatId = ({ remoteJid: remoteJid, participant: participant, fromMe: fromMe }) => {
83
+ if (isJidBroadcast(remoteJid) && !isJidStatusBroadcast(remoteJid) && !fromMe) {
84
+ return participant;
84
85
  }
85
- return remoteJid
86
- }
87
-
88
- /**
89
- * Decrypt a poll vote
90
- * @param vote encrypted vote
91
- * @param ctx additional info about the poll required for decryption
92
- * @returns list of SHA256 options
93
- */
94
- function decryptPollVote({ encPayload, encIv }, { pollCreatorJid, pollMsgId, pollEncKey, voterJid, }) {
86
+ return remoteJid;
87
+ };
88
+ function decryptPollVote(
89
+ { encPayload: encPayload, encIv: encIv },
90
+ {
91
+ pollCreatorJid: pollCreatorJid,
92
+ pollMsgId: pollMsgId,
93
+ pollEncKey: pollEncKey,
94
+ voterJid: voterJid,
95
+ }
96
+ ) {
95
97
  const sign = Buffer.concat([
96
98
  toBinary(pollMsgId),
97
99
  toBinary(pollCreatorJid),
98
100
  toBinary(voterJid),
99
- toBinary('Poll Vote'),
100
- new Uint8Array([1])
101
- ])
102
- const key0 = crypto_1.hmacSign(pollEncKey, new Uint8Array(32), 'sha256')
103
- const decKey = crypto_1.hmacSign(sign, key0, 'sha256')
104
- const aad = toBinary(`${pollMsgId}\u0000${voterJid}`)
105
- const decrypted = crypto_1.aesDecryptGCM(encPayload, decKey, encIv, aad)
106
- return WAProto_1.proto.Message.PollVoteMessage.decode(decrypted)
101
+ toBinary("Poll Vote"),
102
+ new Uint8Array([1]),
103
+ ]);
104
+ const key0 = hmacSign(pollEncKey, new Uint8Array(32), "sha256");
105
+ const decKey = hmacSign(sign, key0, "sha256");
106
+ const aad = toBinary(`${pollMsgId}\0${voterJid}`);
107
+ const decrypted = aesDecryptGCM(encPayload, decKey, encIv, aad);
108
+ return proto.Message.PollVoteMessage.decode(decrypted);
109
+ function toBinary(txt) {
110
+ return Buffer.from(txt);
111
+ }
112
+ }
113
+ function decryptEventEdit(
114
+ { encPayload: encPayload, encIv: encIv },
115
+ {
116
+ eventCreatorJid: eventCreatorJid,
117
+ eventMsgId: eventMsgId,
118
+ eventEncKey: eventEncKey,
119
+ responderJid: responderJid,
120
+ }
121
+ ) {
122
+ const sign = Buffer.concat([
123
+ toBinary(eventMsgId),
124
+ toBinary(eventCreatorJid),
125
+ toBinary(responderJid),
126
+ toBinary("Event Edit"),
127
+ new Uint8Array([1]),
128
+ ]);
129
+ const key0 = hmacSign(eventEncKey, new Uint8Array(32), "sha256");
130
+ const decKey = hmacSign(sign, key0, "sha256");
131
+ const decrypted = aesDecryptGCM(encPayload, decKey, encIv, null);
132
+ return proto.Message.decode(decrypted);
133
+ function toBinary(txt) {
134
+ return Buffer.from(txt);
135
+ }
136
+ }
137
+ function decryptEventResponse(
138
+ { encPayload: encPayload, encIv: encIv },
139
+ {
140
+ eventCreatorJid: eventCreatorJid,
141
+ eventMsgId: eventMsgId,
142
+ eventEncKey: eventEncKey,
143
+ responderJid: responderJid,
144
+ }
145
+ ) {
146
+ const sign = Buffer.concat([
147
+ toBinary(eventMsgId),
148
+ toBinary(eventCreatorJid),
149
+ toBinary(responderJid),
150
+ toBinary("Event Response"),
151
+ new Uint8Array([1]),
152
+ ]);
153
+ const key0 = hmacSign(eventEncKey, new Uint8Array(32), "sha256");
154
+ const decKey = hmacSign(sign, key0, "sha256");
155
+ const aad = toBinary(`${eventMsgId}\0${responderJid}`);
156
+ const decrypted = aesDecryptGCM(encPayload, decKey, encIv, aad);
157
+ return proto.Message.EventResponseMessage.decode(decrypted);
158
+ function toBinary(txt) {
159
+ return Buffer.from(txt);
160
+ }
161
+ }
162
+ function decryptComment(
163
+ { encPayload: encPayload, encIv: encIv },
164
+ {
165
+ commentCreatorJid: commentCreatorJid,
166
+ commentMsgId: commentMsgId,
167
+ commentEncKey: commentEncKey,
168
+ commentJid: commentJid,
169
+ }
170
+ ) {
171
+ const sign = Buffer.concat([
172
+ toBinary(commentMsgId),
173
+ toBinary(commentCreatorJid),
174
+ toBinary(commentJid),
175
+ toBinary("Enc Comment"),
176
+ new Uint8Array([1]),
177
+ ]);
178
+ const key0 = hmacSign(commentEncKey, new Uint8Array(32), "sha256");
179
+ const decKey = hmacSign(sign, key0, "sha256");
180
+ const decrypted = aesDecryptGCM(encPayload, decKey, encIv, null);
181
+ return proto.Message.decode(decrypted);
182
+ function toBinary(txt) {
183
+ return Buffer.from(txt);
184
+ }
185
+ }
186
+ function decryptReaction(
187
+ { encPayload: encPayload, encIv: encIv },
188
+ {
189
+ reactionCreatorJid: reactionCreatorJid,
190
+ reactionMsgId: reactionMsgId,
191
+ reactionEncKey: reactionEncKey,
192
+ reactionJid: reactionJid,
193
+ }
194
+ ) {
195
+ const sign = Buffer.concat([
196
+ toBinary(reactionMsgId),
197
+ toBinary(reactionCreatorJid),
198
+ toBinary(reactionJid),
199
+ toBinary("Enc Reaction"),
200
+ new Uint8Array([1]),
201
+ ]);
202
+ const key0 = hmacSign(reactionEncKey, new Uint8Array(32), "sha256");
203
+ const decKey = hmacSign(sign, key0, "sha256");
204
+ const decrypted = aesDecryptGCM(encPayload, decKey, encIv, null);
205
+ return proto.Message.ReactionMessage.decode(decrypted);
107
206
  function toBinary(txt) {
108
- return Buffer.from(txt)
207
+ return Buffer.from(txt);
109
208
  }
110
209
  }
111
-
112
- const processMessage = async (message, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, signalRepository, keyStore, logger, options, getMessage }) => {
113
- const meId = creds.me.id
114
- const { accountSettings } = creds
115
- const chat = { id: WABinary_1.jidNormalizedUser(getChatId(message.key)) }
116
- const isRealMsg = isRealMessage(message, meId)
210
+ const processMessage = async (
211
+ message,
212
+ {
213
+ shouldProcessHistoryMsg: shouldProcessHistoryMsg,
214
+ placeholderResendCache: placeholderResendCache,
215
+ ev: ev,
216
+ creds: creds,
217
+ signalRepository: signalRepository,
218
+ keyStore: keyStore,
219
+ logger: logger,
220
+ options: options,
221
+ getMessage: getMessage,
222
+ }
223
+ ) => {
224
+ const meId = creds.me.id;
225
+ const meLid = creds.me.lid;
226
+ const { accountSettings: accountSettings } = creds;
227
+ const chat = { id: jidNormalizedUser(getChatId(message.key)) };
228
+ const isRealMsg = isRealMessage(message);
117
229
  if (isRealMsg) {
118
- chat.messages = [{ message }]
119
- chat.conversationTimestamp = generics_1.toNumber(message.messageTimestamp)
120
- // only increment unread count if not CIPHERTEXT and from another person
230
+ chat.messages = [{ message: message }];
231
+ chat.conversationTimestamp = toNumber(message.messageTimestamp);
121
232
  if (shouldIncrementChatUnread(message)) {
122
- chat.unreadCount = (chat.unreadCount || 0) + 1
233
+ chat.unreadCount = (chat.unreadCount || 0) + 1;
123
234
  }
124
235
  }
125
- const content = messages_1.normalizeMessageContent(message.message)
126
- // unarchive chat if it's a real message, or someone reacted to our message
127
- // and we've the unarchive chats setting on
128
- if (isRealMsg || content?.reactionMessage?.key?.fromMe
129
- && accountSettings?.unarchiveChats) {
130
- chat.archived = false
131
- chat.readOnly = false
236
+ const content = normalizeMessageContent(message.message);
237
+ if (isRealMsg || (content?.reactionMessage?.key?.fromMe && accountSettings?.unarchiveChats)) {
238
+ chat.archived = false;
239
+ chat.readOnly = false;
132
240
  }
133
- const protocolMsg = content?.protocolMessage
241
+ const protocolMsg = content?.protocolMessage;
134
242
  if (protocolMsg) {
135
243
  switch (protocolMsg.type) {
136
- case WAProto_1.proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION:
137
- const histNotification = protocolMsg.historySyncNotification
138
- const process = shouldProcessHistoryMsg
139
- const isLatest = !creds.processedHistoryMessages?.length
140
- logger?.info({
141
- histNotification,
142
- process,
143
- id: message.key.id,
144
- isLatest,
145
- }, 'got history notification')
244
+ case proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION:
245
+ const histNotification = protocolMsg.historySyncNotification;
246
+ const process = shouldProcessHistoryMsg;
247
+ const isLatest = !creds.processedHistoryMessages?.length;
248
+ logger?.info(
249
+ {
250
+ histNotification: histNotification,
251
+ process: process,
252
+ id: message.key.id,
253
+ isLatest: isLatest,
254
+ },
255
+ "got history notification"
256
+ );
146
257
  if (process) {
147
- if (histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND) {
148
- ev.emit('creds.update', {
258
+ if (histNotification.syncType !== proto.HistorySync.HistorySyncType.ON_DEMAND) {
259
+ ev.emit("creds.update", {
149
260
  processedHistoryMessages: [
150
261
  ...(creds.processedHistoryMessages || []),
151
- { key: message.key, messageTimestamp: message.messageTimestamp }
152
- ]
153
- })
262
+ {
263
+ key: message.key,
264
+ messageTimestamp: message.messageTimestamp,
265
+ },
266
+ ],
267
+ });
154
268
  }
155
- const data = await history_1.downloadAndProcessHistorySyncNotification(histNotification, options)
156
- ev.emit('messaging-history.set', {
269
+ const data = await downloadAndProcessHistorySyncNotification(
270
+ histNotification,
271
+ options
272
+ );
273
+ ev.emit("messaging-history.set", {
157
274
  ...data,
158
- isLatest: histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND
159
- ? isLatest
160
- : undefined,
161
- peerDataRequestSessionId: histNotification.peerDataRequestSessionId
162
- })
275
+ isLatest:
276
+ histNotification.syncType !==
277
+ proto.HistorySync.HistorySyncType.ON_DEMAND
278
+ ? isLatest
279
+ : undefined,
280
+ peerDataRequestSessionId: histNotification.peerDataRequestSessionId,
281
+ });
163
282
  }
164
- break
165
- case WAProto_1.proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE:
166
- const keys = protocolMsg.appStateSyncKeyShare.keys
283
+ break;
284
+ case proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE:
285
+ const keys = protocolMsg.appStateSyncKeyShare.keys;
167
286
  if (keys?.length) {
168
- let newAppStateSyncKeyId = ''
287
+ let newAppStateSyncKeyId = "";
169
288
  await keyStore.transaction(async () => {
170
- const newKeys = []
171
- for (const { keyData, keyId } of keys) {
172
- const strKeyId = Buffer.from(keyId.keyId).toString('base64')
173
- newKeys.push(strKeyId)
174
- await keyStore.set({ 'app-state-sync-key': { [strKeyId]: keyData } })
175
- newAppStateSyncKeyId = strKeyId
289
+ const newKeys = [];
290
+ for (const { keyData: keyData, keyId: keyId } of keys) {
291
+ const strKeyId = Buffer.from(keyId.keyId).toString("base64");
292
+ newKeys.push(strKeyId);
293
+ await keyStore.set({
294
+ "app-state-sync-key": { [strKeyId]: keyData },
295
+ });
296
+ newAppStateSyncKeyId = strKeyId;
176
297
  }
177
- logger?.info({ newAppStateSyncKeyId, newKeys }, 'injecting new app state sync keys')
178
- }, meId)
179
- ev.emit('creds.update', { myAppStateKeyId: newAppStateSyncKeyId })
180
- }
181
- else {
182
- logger?.info({ protocolMsg }, 'recv app state sync with 0 keys')
298
+ logger?.info(
299
+ { newAppStateSyncKeyId: newAppStateSyncKeyId, newKeys: newKeys },
300
+ "injecting new app state sync keys"
301
+ );
302
+ }, meId);
303
+ ev.emit("creds.update", { myAppStateKeyId: newAppStateSyncKeyId });
304
+ } else {
305
+ logger?.info({ protocolMsg: protocolMsg }, "recv app state sync with 0 keys");
183
306
  }
184
- break
185
- case WAProto_1.proto.Message.ProtocolMessage.Type.REVOKE:
186
- ev.emit('messages.update', [
307
+ break;
308
+ case proto.Message.ProtocolMessage.Type.REVOKE:
309
+ ev.emit("messages.update", [
187
310
  {
188
- key: {
189
- ...message.key,
190
- id: protocolMsg.key.id
311
+ key: { ...message.key, id: protocolMsg.key.id },
312
+ update: {
313
+ message: null,
314
+ messageStubType: WAMessageStubType.REVOKE,
315
+ key: message.key,
191
316
  },
192
- update: { message: null, messageStubType: Types_1.WAMessageStubType.REVOKE, key: message.key }
193
- }
194
- ])
195
- break
196
- case WAProto_1.proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING:
317
+ },
318
+ ]);
319
+ break;
320
+ case proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING:
197
321
  Object.assign(chat, {
198
- ephemeralSettingTimestamp: generics_1.toNumber(message.messageTimestamp),
199
- ephemeralExpiration: protocolMsg.ephemeralExpiration || null
200
- })
201
- break
202
- case WAProto_1.proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE:
203
- const response = protocolMsg.peerDataOperationRequestResponseMessage
322
+ ephemeralSettingTimestamp: toNumber(message.messageTimestamp),
323
+ ephemeralExpiration: protocolMsg.ephemeralExpiration || null,
324
+ });
325
+ break;
326
+ case proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE:
327
+ const response = protocolMsg.peerDataOperationRequestResponseMessage;
204
328
  if (response) {
205
- await placeholderResendCache?.del(response.stanzaId)
206
- // TODO: IMPLEMENT HISTORY SYNC ETC (sticker uploads etc.).
207
- const { peerDataOperationResult } = response
329
+ await placeholderResendCache?.del(response.stanzaId);
330
+ const { peerDataOperationResult: peerDataOperationResult } = response;
208
331
  for (const result of peerDataOperationResult) {
209
- const { placeholderMessageResendResponse: retryResponse } = result
210
- //eslint-disable-next-line max-depth
332
+ const { placeholderMessageResendResponse: retryResponse } = result;
211
333
  if (retryResponse) {
212
- const webMessageInfo = WAProto_1.proto.WebMessageInfo.decode(retryResponse.webMessageInfoBytes)
213
- // wait till another upsert event is available, don't want it to be part of the PDO response message
334
+ const webMessageInfo = proto.WebMessageInfo.decode(
335
+ retryResponse.webMessageInfoBytes
336
+ );
214
337
  setTimeout(() => {
215
- ev.emit('messages.upsert', {
338
+ ev.emit("messages.upsert", {
216
339
  messages: [webMessageInfo],
217
- type: 'notify',
218
- requestId: response.stanzaId
219
- })
220
- }, 500)
340
+ type: "notify",
341
+ requestId: response.stanzaId,
342
+ });
343
+ }, 500);
221
344
  }
222
345
  }
223
346
  }
224
- break
225
- case WAProto_1.proto.Message.ProtocolMessage.Type.MESSAGE_EDIT:
226
- ev.emit('messages.update', [
347
+ break;
348
+ case proto.Message.ProtocolMessage.Type.MESSAGE_EDIT:
349
+ ev.emit("messages.update", [
227
350
  {
228
- // flip the sender / fromMe properties because they're in the perspective of the sender
229
351
  key: { ...message.key, id: protocolMsg.key?.id },
230
352
  update: {
231
353
  message: {
232
- editedMessage: {
233
- message: protocolMsg.editedMessage
234
- }
354
+ editedMessage: { message: protocolMsg.editedMessage },
235
355
  },
236
356
  messageTimestamp: protocolMsg.timestampMs
237
- ? Math.floor(generics_1.toNumber(protocolMsg.timestampMs) / 1000)
238
- : message.messageTimestamp
239
- }
357
+ ? Math.floor(toNumber(protocolMsg.timestampMs) / 1e3)
358
+ : message.messageTimestamp,
359
+ },
360
+ },
361
+ ]);
362
+ break;
363
+ case proto.Message.ProtocolMessage.Type.GROUP_MEMBER_LABEL_CHANGE:
364
+ const labelAssociationMsg = protocolMsg.memberLabel;
365
+ if (labelAssociationMsg?.label) {
366
+ ev.emit("group.member-tag.update", {
367
+ groupId: chat.id,
368
+ label: labelAssociationMsg.label,
369
+ participant: message.key.participant,
370
+ participantAlt: message.key.participantAlt,
371
+ messageTimestamp: Number(message.messageTimestamp),
372
+ });
373
+ }
374
+ break;
375
+ case proto.Message.ProtocolMessage.Type.LID_MIGRATION_MAPPING_SYNC:
376
+ const encodedPayload =
377
+ protocolMsg.lidMigrationMappingSyncMessage?.encodedMappingPayload;
378
+ const {
379
+ pnToLidMappings: pnToLidMappings,
380
+ chatDbMigrationTimestamp: chatDbMigrationTimestamp,
381
+ } = proto.LIDMigrationMappingSyncPayload.decode(encodedPayload);
382
+ logger?.debug(
383
+ {
384
+ pnToLidMappings: pnToLidMappings,
385
+ chatDbMigrationTimestamp: chatDbMigrationTimestamp,
386
+ },
387
+ "got lid mappings and chat db migration timestamp"
388
+ );
389
+ const pairs = [];
390
+ for (const {
391
+ pn: pn,
392
+ latestLid: latestLid,
393
+ assignedLid: assignedLid,
394
+ } of pnToLidMappings) {
395
+ const lid = latestLid || assignedLid;
396
+ pairs.push({ lid: `${lid}@lid`, pn: `${pn}@s.whatsapp.net` });
397
+ }
398
+ await signalRepository.lidMapping.storeLIDPNMappings(pairs);
399
+ if (pairs.length) {
400
+ for (const { pn: pn, lid: lid } of pairs) {
401
+ await signalRepository.migrateSession(pn, lid);
240
402
  }
241
- ])
242
- break
243
- case WAProto_1.proto.Message.ProtocolMessage.Type.LID_MIGRATION_MAPPING_SYNC:
244
- const encodedPayload = protocolMsg.lidMigrationMappingSyncMessage?.encodedMappingPayload
245
- const { pnToLidMappings, chatDbMigrationTimestamp } = WAProto_1.proto.LIDMigrationMappingSyncPayload.decode(encodedPayload)
246
-
247
- logger?.debug({ pnToLidMappings, chatDbMigrationTimestamp }, 'got lid mappings and chat db migration timestamp')
248
-
249
- const pairs = []
250
-
251
- for (const { pn, latestLid, assignedLid } of pnToLidMappings) {
252
- const lid = latestLid || assignedLid
253
- pairs.push({ lid: `${lid}@lid`, pn: `${pn}@s.whatsapp.net` })
254
403
  }
255
-
256
- await signalRepository.lidMapping.storeLIDPNMappings(pairs)
257
- break
258
- case WAProto_1.proto.Message.ProtocolMessage.Type.LIMIT_SHARING:
259
- ev.emit('limit-sharing.update', {
260
- id: message.key.remoteJid,
261
- author: WABinary_1.areJidsSameUser(message.key.remoteJid, protocolMsg.key.remoteJid) ? WABinary_1.jidNormalizedUser(meId) : message.key.remoteJid,
262
- action: `${protocolMsg.limitSharing.sharingLimited ? 'on' : 'off'}`,
263
- trigger: protocolMsg.limitSharing.trigger,
264
- update_time: protocolMsg.limitSharing.limitSharingSettingTimestamp
265
- })
266
- break
404
+ break;
405
+ case proto.Message.ProtocolMessage.Type.LIMIT_SHARING:
406
+ ev.emit("limit-sharing.update", {
407
+ id: message.key.remoteJid,
408
+ author: areJidsSameUser(message.key.remoteJid, protocolMsg.key.remoteJid)
409
+ ? jidNormalizedUser(meId)
410
+ : message.key.remoteJid,
411
+ action: `${protocolMsg.limitSharing.sharingLimited ? "on" : "off"}`,
412
+ trigger: protocolMsg.limitSharing.trigger,
413
+ update_time: protocolMsg.limitSharing.limitSharingSettingTimestamp,
414
+ });
415
+ break;
267
416
  }
268
- }
269
- else if (content?.reactionMessage) {
270
- const reaction = {
271
- ...content.reactionMessage,
272
- key: message.key,
273
- }
274
- ev.emit('messages.reaction', [{
275
- reaction,
276
- key: content.reactionMessage?.key
277
- }])
278
- }
279
- else if (message.messageStubType) {
280
- const jid = message.key?.remoteJid
281
- //let actor = whatsappID (message.participant)
282
- let participants
283
- const emitParticipantsUpdate = (action) => (ev.emit('group-participants.update', { id: jid, author: message.participant, participants, action }))
417
+ } else if (content?.reactionMessage) {
418
+ const reaction = { ...content.reactionMessage, key: message.key };
419
+ ev.emit("messages.reaction", [{ reaction: reaction, key: content.reactionMessage?.key }]);
420
+ } else if (message.messageStubType) {
421
+ const jid = message.key?.remoteJid;
422
+ let participants;
423
+ const emitParticipantsUpdate = (action) =>
424
+ ev.emit("group-participants.update", {
425
+ id: jid,
426
+ author: message.key.participant,
427
+ authorPn: message.key.participantAlt,
428
+ participants: participants,
429
+ action: action,
430
+ });
284
431
  const emitGroupUpdate = (update) => {
285
- ev.emit('groups.update', [{ id: jid, ...update, author: message.participant ? message.participant : undefined }])
286
- }
432
+ ev.emit("groups.update", [
433
+ {
434
+ id: jid,
435
+ ...update,
436
+ author: message.key.participant ?? undefined,
437
+ authorPn: message.key.participantAlt,
438
+ },
439
+ ]);
440
+ };
287
441
  const emitGroupRequestJoin = (participant, action, method) => {
288
- ev.emit('group.join-request', { id: jid, author: message.participant, participant, action, method: method })
289
- }
290
- const participantsIncludesMe = () => participants.find(jid => WABinary_1.areJidsSameUser(meId, jid))
442
+ ev.emit("group.join-request", {
443
+ id: jid,
444
+ author: message.key.participant,
445
+ authorPn: message.key.participantAlt,
446
+ participant: participant.lid,
447
+ participantPn: participant.pn,
448
+ action: action,
449
+ method: method,
450
+ });
451
+ };
452
+ const participantsIncludesMe = () =>
453
+ participants.find((jid) => areJidsSameUser(meId, jid.phoneNumber));
291
454
  switch (message.messageStubType) {
292
- case Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER:
293
- participants = message.messageStubParameters || []
294
- emitParticipantsUpdate('modify')
295
- break
296
- case Types_1.WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
297
- participants = message.messageStubParameters || [];
298
- emitParticipantsUpdate('leave');
299
- // mark the chat read only if you left the group
300
- if (participantsIncludesMe()) {
301
- chat.readOnly = true;
302
- }
303
- break;
304
- case Types_1.WAMessageStubType.GROUP_PARTICIPANT_REMOVE:
305
- participants = message.messageStubParameters || []
306
- emitParticipantsUpdate('remove')
307
- // mark the chat read only if you left the group
455
+ case WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER:
456
+ participants = message.messageStubParameters.map((a) => JSON.parse(a)) || [];
457
+ emitParticipantsUpdate("modify");
458
+ break;
459
+ case WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
460
+ case WAMessageStubType.GROUP_PARTICIPANT_REMOVE:
461
+ participants = message.messageStubParameters.map((a) => JSON.parse(a)) || [];
462
+ emitParticipantsUpdate("remove");
308
463
  if (participantsIncludesMe()) {
309
- chat.readOnly = true
464
+ chat.readOnly = true;
310
465
  }
311
- break
312
- case Types_1.WAMessageStubType.GROUP_PARTICIPANT_ADD:
313
- case Types_1.WAMessageStubType.GROUP_PARTICIPANT_INVITE:
314
- let actionGp = 'invite'
315
- participants = message.messageStubParameters || []
316
- if (participantsIncludesMe()) chat.readOnly = false;
317
- if (message?.key?.participant && !participants.includes(message?.key?.participant)) {
318
- actionGp = 'approval-invite'
319
- }
320
- case Types_1.WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN:
321
- participants = message.messageStubParameters || []
466
+ break;
467
+ case WAMessageStubType.GROUP_PARTICIPANT_ADD:
468
+ case WAMessageStubType.GROUP_PARTICIPANT_INVITE:
469
+ case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN:
470
+ participants = message.messageStubParameters.map((a) => JSON.parse(a)) || [];
322
471
  if (participantsIncludesMe()) {
323
- chat.readOnly = false
472
+ chat.readOnly = false;
324
473
  }
325
- emitParticipantsUpdate('add')
326
- break
327
- case Types_1.WAMessageStubType.GROUP_PARTICIPANT_DEMOTE:
328
- case Types_1.WAMessageStubType.COMMUNITY_PARTICIPANT_DEMOTE:
329
- participants = message.messageStubParameters || []
330
- emitParticipantsUpdate('demote')
331
- break
332
- case Types_1.WAMessageStubType.GROUP_PARTICIPANT_PROMOTE:
333
- case Types_1.WAMessageStubType.COMMUNITY_PARTICIPANT_PROMOTE:
334
- participants = message.messageStubParameters || []
335
- emitParticipantsUpdate('promote')
336
- break
337
- case Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE:
338
- const announceValue = message.messageStubParameters?.[0]
339
- emitGroupUpdate({ announce: announceValue === 'true' || announceValue === 'on' })
340
- break
341
- case Types_1.WAMessageStubType.GROUP_CHANGE_RESTRICT:
342
- const restrictValue = message.messageStubParameters?.[0]
343
- emitGroupUpdate({ restrict: restrictValue === 'true' || restrictValue === 'on' })
344
- break
345
- case Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT:
346
- const name = message.messageStubParameters?.[0]
347
- chat.name = name
348
- emitGroupUpdate({ subject: name })
349
- break
350
- case Types_1.WAMessageStubType.GROUP_CHANGE_DESCRIPTION:
351
- const description = message.messageStubParameters?.[0]
352
- chat.description = description
353
- emitGroupUpdate({ desc: description })
354
- break
355
- case Types_1.WAMessageStubType.GROUP_CHANGE_INVITE_LINK:
356
- const code = message.messageStubParameters?.[0]
357
- emitGroupUpdate({ inviteCode: code })
358
- break
359
- case Types_1.WAMessageStubType.GROUP_MEMBER_ADD_MODE:
360
- const memberAddValue = message.messageStubParameters?.[0]
361
- emitGroupUpdate({ memberAddMode: memberAddValue === 'all_member_add' })
362
- break
363
- case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE:
364
- const approvalMode = message.messageStubParameters?.[0]
365
- emitGroupUpdate({ joinApprovalMode: approvalMode === 'on' })
366
- break
367
- case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD:
368
- const participant = message.messageStubParameters?.[0]
369
- const action = message.messageStubParameters?.[1]
370
- const method = message.messageStubParameters?.[2]
371
- emitGroupRequestJoin(participant, action, method)
372
- break
474
+ emitParticipantsUpdate("add");
475
+ break;
476
+ case WAMessageStubType.GROUP_PARTICIPANT_DEMOTE:
477
+ participants = message.messageStubParameters.map((a) => JSON.parse(a)) || [];
478
+ emitParticipantsUpdate("demote");
479
+ break;
480
+ case WAMessageStubType.GROUP_PARTICIPANT_PROMOTE:
481
+ participants = message.messageStubParameters.map((a) => JSON.parse(a)) || [];
482
+ emitParticipantsUpdate("promote");
483
+ break;
484
+ case WAMessageStubType.GROUP_CHANGE_ANNOUNCE:
485
+ const announceValue = message.messageStubParameters?.[0];
486
+ emitGroupUpdate({
487
+ announce: announceValue === "true" || announceValue === "on",
488
+ });
489
+ break;
490
+ case WAMessageStubType.GROUP_CHANGE_RESTRICT:
491
+ const restrictValue = message.messageStubParameters?.[0];
492
+ emitGroupUpdate({
493
+ restrict: restrictValue === "true" || restrictValue === "on",
494
+ });
495
+ break;
496
+ case WAMessageStubType.GROUP_CHANGE_SUBJECT:
497
+ const name = message.messageStubParameters?.[0];
498
+ chat.name = name;
499
+ emitGroupUpdate({ subject: name });
500
+ break;
501
+ case WAMessageStubType.GROUP_CHANGE_DESCRIPTION:
502
+ const description = message.messageStubParameters?.[0];
503
+ chat.description = description;
504
+ emitGroupUpdate({ desc: description });
505
+ break;
506
+ case WAMessageStubType.GROUP_CHANGE_INVITE_LINK:
507
+ const code = message.messageStubParameters?.[0];
508
+ emitGroupUpdate({ inviteCode: code });
509
+ break;
510
+ case WAMessageStubType.GROUP_MEMBER_ADD_MODE:
511
+ const memberAddValue = message.messageStubParameters?.[0];
512
+ emitGroupUpdate({ memberAddMode: memberAddValue === "all_member_add" });
513
+ break;
514
+ case WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE:
515
+ const approvalMode = message.messageStubParameters?.[0];
516
+ emitGroupUpdate({ joinApprovalMode: approvalMode === "on" });
517
+ break;
518
+ case WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD:
519
+ const participant = JSON.parse(message.messageStubParameters?.[0]);
520
+ const action = message.messageStubParameters?.[1];
521
+ const method = message.messageStubParameters?.[2];
522
+ emitGroupRequestJoin(participant, action, method);
523
+ break;
373
524
  }
374
- }
375
- else if (content?.pollUpdateMessage) {
376
- const creationMsgKey = content.pollUpdateMessage.pollCreationMessageKey
377
- // we need to fetch the poll creation message to get the poll enc key
378
- const pollMsg = await getMessage(creationMsgKey)
525
+ } else if (content?.pollUpdateMessage) {
526
+ const pollUpdate = content.pollUpdateMessage;
527
+ const creationMsgKey = pollUpdate.pollCreationMessageKey;
528
+ const pollMsg = await getMessage(creationMsgKey);
379
529
  if (pollMsg) {
380
- const meIdNormalised = WABinary_1.jidNormalizedUser(meId)
381
- const pollCreatorJid = generics_1.getKeyAuthor(creationMsgKey, meIdNormalised)
382
- const voterJid = generics_1.getKeyAuthor(message.key, meIdNormalised)
383
- const pollEncKey = pollMsg.messageContextInfo?.messageSecret
384
530
  try {
385
- const voteMsg = decryptPollVote(content.pollUpdateMessage.vote, {
386
- pollEncKey,
387
- pollCreatorJid,
388
- pollMsgId: creationMsgKey.id,
389
- voterJid,
390
- })
391
- ev.emit('messages.update', [
531
+ const meLidNormalised = jidNormalizedUser(meLid);
532
+ const deviceType = getDevice(creationMsgKey.id);
533
+ const pollCreationFromMe = deviceType === "baileys" ? true : false;
534
+ const pollEncKey = pollMsg.messageContextInfo?.messageSecret;
535
+ const voterJid = getKeyAuthor(message.key, meLidNormalised);
536
+ let pollCreatorJid = getKeyAuthor(creationMsgKey, meLidNormalised);
537
+ if (pollCreationFromMe) {
538
+ pollCreatorJid = meLidNormalised;
539
+ }
540
+ if (!pollEncKey) {
541
+ logger?.warn(
542
+ { vote: pollUpdate.vote, creationMsgKey: creationMsgKey },
543
+ "poll creation: missing messageSecret for decryption"
544
+ );
545
+ } else {
546
+ const voteMsg = decryptPollVote(pollUpdate.vote, {
547
+ pollEncKey: pollEncKey,
548
+ pollCreatorJid: pollCreatorJid,
549
+ pollMsgId: creationMsgKey.id,
550
+ voterJid: voterJid,
551
+ });
552
+ ev.emit("messages.update", [
553
+ {
554
+ key: creationMsgKey,
555
+ update: {
556
+ pollUpdates: [
557
+ {
558
+ pollUpdateMessageKey: message.key,
559
+ vote: voteMsg,
560
+ senderTimestampMs:
561
+ content.pollUpdateMessage.senderTimestampMs.toNumber(),
562
+ },
563
+ ],
564
+ },
565
+ },
566
+ ]);
567
+ }
568
+ } catch (err) {
569
+ logger?.warn(
570
+ { err: err, creationMsgKey: creationMsgKey },
571
+ "failed to decrypt poll vote"
572
+ );
573
+ }
574
+ } else {
575
+ logger?.warn(
576
+ { creationMsgKey: creationMsgKey },
577
+ "poll creation message not found, cannot decrypt update"
578
+ );
579
+ }
580
+ } else if (content?.secretEncryptedMessage) {
581
+ const encEventEdit = content.secretEncryptedMessage;
582
+ const creationMsgKey = encEventEdit.targetMessageKey;
583
+ if (
584
+ proto.Message.SecretEncryptedMessage.SecretEncType[encEventEdit.secretEncType] !==
585
+ "EVENT_EDIT"
586
+ )
587
+ return;
588
+ const eventMsg = await getMessage(creationMsgKey);
589
+ if (eventMsg) {
590
+ try {
591
+ const meLidNormalised = jidNormalizedUser(meLid);
592
+ const eventCreatorJid = getKeyAuthor(message.key, meLidNormalised);
593
+ const responderJid = getKeyAuthor(message.key, meLidNormalised);
594
+ const eventEncKey = eventMsg.messageContextInfo?.messageSecret;
595
+ if (!eventEncKey) {
596
+ logger?.warn(
597
+ { encEventEdit: encEventEdit, creationMsgKey: creationMsgKey },
598
+ "event edit: missing messageSecret for decryption"
599
+ );
600
+ } else {
601
+ const responseMsg = decryptEventEdit(encEventEdit, {
602
+ eventEncKey: eventEncKey,
603
+ eventCreatorJid: eventCreatorJid,
604
+ eventMsgId: creationMsgKey.id,
605
+ responderJid: responderJid,
606
+ });
607
+ const content = normalizeMessageContent(responseMsg);
608
+ const protocolMsg = content?.protocolMessage;
609
+ ev.emit("messages.update", [
610
+ {
611
+ key: { ...message.key, id: protocolMsg.key?.id },
612
+ update: {
613
+ message: {
614
+ messageContextInfo: responseMsg.messageContextInfo,
615
+ editedMessage: { message: protocolMsg.editedMessage },
616
+ },
617
+ messageTimestamp: protocolMsg.timestampMs
618
+ ? Math.floor(toNumber(protocolMsg.timestampMs) / 1e3)
619
+ : message.messageTimestamp,
620
+ },
621
+ },
622
+ ]);
623
+ }
624
+ } catch (err) {
625
+ logger?.warn(
392
626
  {
393
- key: creationMsgKey,
394
- update: {
395
- pollUpdates: [
396
- {
397
- pollUpdateMessageKey: message.key,
398
- vote: voteMsg,
399
- senderTimestampMs: content.pollUpdateMessage.senderTimestampMs.toNumber(),
400
- }
401
- ]
402
- }
403
- }
404
- ])
627
+ err: err,
628
+ creationMsgKey: creationMsgKey,
629
+ encEventEdit: encEventEdit,
630
+ },
631
+ "failed to decrypt event edit"
632
+ );
405
633
  }
406
- catch (err) {
407
- logger?.warn({ err, creationMsgKey }, 'failed to decrypt poll vote')
634
+ } else {
635
+ logger?.warn(
636
+ { encEventEdit: encEventEdit, creationMsgKey: creationMsgKey },
637
+ "event creation message not found, cannot decrypt update"
638
+ );
639
+ }
640
+ } else if (content?.encEventResponseMessage) {
641
+ const encEventResponse = content.encEventResponseMessage;
642
+ const creationMsgKey = encEventResponse.eventCreationMessageKey;
643
+ const eventMsg = await getMessage(creationMsgKey);
644
+ if (eventMsg) {
645
+ try {
646
+ const meLidNormalised = jidNormalizedUser(meLid);
647
+ const eventCreatorJid = getKeyAuthor(creationMsgKey, meLidNormalised);
648
+ const responderJid = getKeyAuthor(message.key, meLidNormalised);
649
+ const eventEncKey = eventMsg.messageContextInfo?.messageSecret;
650
+ if (!eventEncKey) {
651
+ logger?.warn(
652
+ {
653
+ encEventResponse: encEventResponse,
654
+ creationMsgKey: creationMsgKey,
655
+ },
656
+ "event response: missing messageSecret for decryption"
657
+ );
658
+ } else {
659
+ const responseMsg = decryptEventResponse(encEventResponse, {
660
+ eventEncKey: eventEncKey,
661
+ eventCreatorJid: eventCreatorJid,
662
+ eventMsgId: creationMsgKey.id,
663
+ responderJid: responderJid,
664
+ });
665
+ const eventResponse = {
666
+ eventResponseMessageKey: message.key,
667
+ senderTimestampMs: responseMsg.timestampMs,
668
+ response: responseMsg,
669
+ };
670
+ ev.emit("messages.update", [
671
+ {
672
+ key: creationMsgKey,
673
+ update: { eventResponses: [eventResponse] },
674
+ },
675
+ ]);
676
+ }
677
+ } catch (err) {
678
+ logger?.warn(
679
+ {
680
+ err: err,
681
+ creationMsgKey: creationMsgKey,
682
+ encEventResponse: encEventResponse,
683
+ },
684
+ "failed to decrypt event response"
685
+ );
408
686
  }
687
+ } else {
688
+ logger?.warn(
689
+ { encEventResponse: encEventResponse, creationMsgKey: creationMsgKey },
690
+ "event creation message not found, cannot decrypt update"
691
+ );
409
692
  }
410
- else {
411
- logger?.warn({ creationMsgKey }, 'poll creation message not found, cannot decrypt update')
693
+ } else if (content?.encCommentMessage) {
694
+ const encComment = content.encCommentMessage;
695
+ const creationMsgKey = encComment.targetMessageKey;
696
+ const commentMsg = await getMessage(creationMsgKey);
697
+ if (commentMsg) {
698
+ try {
699
+ const meLidNormalised = jidNormalizedUser(meLid);
700
+ const commentCreatorJid = creationMsgKey.participant
701
+ ? creationMsgKey.participant
702
+ : message.key?.participant
703
+ ? message.key.participant
704
+ : meLidNormalised;
705
+ const commentJid = message.key?.participant
706
+ ? message.key.participant
707
+ : creationMsgKey.participant
708
+ ? creationMsgKey.participant
709
+ : meLidNormalised;
710
+ const commentEncKey = commentMsg.messageContextInfo?.messageSecret;
711
+ if (!commentEncKey) {
712
+ logger?.warn(
713
+ { encComment: encComment, creationMsgKey: creationMsgKey },
714
+ "comment message: missing messageSecret for decryption"
715
+ );
716
+ } else {
717
+ const responseMsg = decryptComment(encComment, {
718
+ commentEncKey: commentEncKey,
719
+ commentCreatorJid: commentCreatorJid,
720
+ commentMsgId: creationMsgKey.id,
721
+ commentJid: commentJid,
722
+ });
723
+ ev.emit("messages.upsert", {
724
+ messages: [{ key: message.key, message: responseMsg }],
725
+ type: "append",
726
+ });
727
+ }
728
+ } catch (err) {
729
+ logger?.warn(
730
+ { err: err, creationMsgKey: creationMsgKey, encComment: encComment },
731
+ "failed to decrypt comment message"
732
+ );
733
+ }
734
+ } else {
735
+ logger?.warn(
736
+ { encComment: encComment, creationMsgKey: creationMsgKey },
737
+ "creation message not found, cannot decrypt"
738
+ );
739
+ }
740
+ } else if (content?.encReactionMessage) {
741
+ const encReaction = content.encReactionMessage;
742
+ const creationMsgKey = encReaction.targetMessageKey;
743
+ const reactMsg = await getMessage(creationMsgKey);
744
+ if (reactMsg) {
745
+ try {
746
+ const meLidNormalised = jidNormalizedUser(meLid);
747
+ const reactionCreatorJid = creationMsgKey.participant
748
+ ? creationMsgKey.participant
749
+ : message.key?.participant
750
+ ? message.key.participant
751
+ : meLidNormalised;
752
+ const reactionJid = message.key?.participant
753
+ ? message.key.participant
754
+ : creationMsgKey.participant
755
+ ? creationMsgKey.participant
756
+ : meLidNormalised;
757
+ const reactionEncKey = reactMsg.messageContextInfo?.messageSecret;
758
+ if (!reactionEncKey) {
759
+ logger?.warn(
760
+ { encReaction: encReaction, creationMsgKey: creationMsgKey },
761
+ "reaction: missing messageSecret for decryption"
762
+ );
763
+ } else {
764
+ const responseMsg = decryptReaction(encReaction, {
765
+ reactionEncKey: reactionEncKey,
766
+ reactionCreatorJid: reactionCreatorJid,
767
+ reactionMsgId: creationMsgKey.id,
768
+ reactionJid: reactionJid,
769
+ });
770
+ const Reaction = {
771
+ key: message.key,
772
+ message: {
773
+ reactionMessage: {
774
+ key: creationMsgKey,
775
+ text: responseMsg.text,
776
+ senderTimestampMs: responseMsg.senderTimestampMs,
777
+ },
778
+ },
779
+ };
780
+ ev.emit("messages.upsert", { messages: [Reaction], type: "append" });
781
+ }
782
+ } catch (err) {
783
+ logger?.warn(
784
+ {
785
+ err: err,
786
+ creationMsgKey: creationMsgKey,
787
+ encReaction: encReaction,
788
+ },
789
+ "failed to decrypt reaction"
790
+ );
791
+ }
792
+ } else {
793
+ logger?.warn(
794
+ { encReaction: encReaction, creationMsgKey: creationMsgKey },
795
+ "creation message not found, cannot decrypt"
796
+ );
412
797
  }
413
798
  }
414
799
  if (Object.keys(chat).length > 1) {
415
- ev.emit('chats.update', [chat])
800
+ ev.emit("chats.update", [chat]);
416
801
  }
417
- }
418
-
802
+ };
419
803
  module.exports = {
420
- cleanMessage,
421
- isRealMessage,
422
- shouldIncrementChatUnread,
423
- getChatId,
424
- decryptPollVote,
425
- processMessage
426
- }
804
+ cleanMessage: cleanMessage,
805
+ isRealMessage: isRealMessage,
806
+ shouldIncrementChatUnread: shouldIncrementChatUnread,
807
+ getChatId: getChatId,
808
+ decryptPollVote: decryptPollVote,
809
+ decryptEventEdit: decryptEventEdit,
810
+ decryptEventResponse: decryptEventResponse,
811
+ decryptComment: decryptComment,
812
+ decryptReaction: decryptReaction,
813
+ processMessage: processMessage,
814
+ };