jagproject 26.3.23 → 26.3.26

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 (209) hide show
  1. package/WAProto/GenerateStatics.sh +3 -4
  2. package/WAProto/WAProto.proto +1215 -511
  3. package/WAProto/fix-imports.js +73 -0
  4. package/WAProto/index.d.ts +14017 -0
  5. package/WAProto/index.js +64857 -145167
  6. package/engine-requirements.js +4 -7
  7. package/lib/Defaults/index.d.ts +74 -0
  8. package/lib/Defaults/index.js +49 -35
  9. package/lib/Defaults/phonenumber-mcc.json +223 -0
  10. package/lib/Defaults/wileys-version.json +2 -2
  11. package/lib/Signal/Group/ciphertext-message.d.ts +10 -0
  12. package/lib/Signal/Group/group-session-builder.d.ts +15 -0
  13. package/lib/Signal/Group/group-session-builder.js +5 -3
  14. package/lib/Signal/Group/group_cipher.d.ts +17 -0
  15. package/lib/Signal/Group/group_cipher.js +35 -46
  16. package/lib/Signal/Group/index.d.ts +12 -0
  17. package/lib/Signal/Group/index.js +21 -21
  18. package/lib/Signal/Group/keyhelper.d.ts +11 -0
  19. package/lib/Signal/Group/keyhelper.js +2 -2
  20. package/lib/Signal/Group/sender-chain-key.d.ts +14 -0
  21. package/lib/Signal/Group/sender-chain-key.js +5 -10
  22. package/lib/Signal/Group/sender-key-distribution-message.d.ts +17 -0
  23. package/lib/Signal/Group/sender-key-distribution-message.js +7 -7
  24. package/lib/Signal/Group/sender-key-message.d.ts +19 -0
  25. package/lib/Signal/Group/sender-key-message.js +8 -8
  26. package/lib/Signal/Group/sender-key-name.d.ts +18 -0
  27. package/lib/Signal/Group/sender-key-record.d.ts +31 -0
  28. package/lib/Signal/Group/sender-key-record.js +7 -16
  29. package/lib/Signal/Group/sender-key-state.d.ts +39 -0
  30. package/lib/Signal/Group/sender-key-state.js +25 -37
  31. package/lib/Signal/Group/sender-message-key.d.ts +12 -0
  32. package/lib/Signal/Group/sender-message-key.js +2 -2
  33. package/lib/Signal/libsignal.d.ts +5 -0
  34. package/lib/Signal/libsignal.js +358 -54
  35. package/lib/Signal/lid-mapping.d.ts +19 -0
  36. package/lib/Signal/lid-mapping.js +274 -0
  37. package/lib/Socket/Client/index.d.ts +3 -0
  38. package/lib/Socket/Client/index.js +2 -2
  39. package/lib/Socket/Client/types.d.ts +16 -0
  40. package/lib/Socket/Client/types.js +1 -0
  41. package/lib/Socket/Client/websocket.d.ts +13 -0
  42. package/lib/Socket/Client/websocket.js +18 -30
  43. package/lib/Socket/business.d.ts +202 -0
  44. package/lib/Socket/business.js +160 -38
  45. package/lib/Socket/chats.d.ts +111 -0
  46. package/lib/Socket/chats.js +497 -314
  47. package/lib/Socket/communities.d.ts +258 -0
  48. package/lib/Socket/communities.js +438 -0
  49. package/lib/Socket/community.js +333 -0
  50. package/lib/Socket/groups.d.ts +150 -0
  51. package/lib/Socket/groups.js +229 -91
  52. package/lib/Socket/index.d.ts +245 -0
  53. package/lib/Socket/index.js +9 -6
  54. package/lib/Socket/messages-recv.d.ts +187 -0
  55. package/lib/Socket/messages-recv.js +1105 -501
  56. package/lib/Socket/messages-send.d.ts +183 -0
  57. package/lib/Socket/messages-send.js +1181 -501
  58. package/lib/Socket/mex.d.ts +3 -0
  59. package/lib/Socket/mex.js +45 -0
  60. package/lib/Socket/newsletter.d.ts +160 -0
  61. package/lib/Socket/newsletter.js +227 -200
  62. package/lib/Socket/socket.d.ts +55 -0
  63. package/lib/Socket/socket.js +507 -206
  64. package/lib/Socket/usync.js +6 -6
  65. package/lib/Store/index.js +17 -5
  66. package/lib/Store/make-cache-manager-store.js +83 -0
  67. package/lib/Store/make-in-memory-store.js +48 -89
  68. package/lib/Store/make-ordered-dictionary.js +1 -1
  69. package/lib/Types/Auth.d.ts +116 -0
  70. package/lib/Types/Bussines.d.ts +25 -0
  71. package/lib/Types/Bussines.js +2 -0
  72. package/lib/Types/Call.d.ts +15 -0
  73. package/lib/Types/Chat.d.ts +123 -0
  74. package/lib/Types/Chat.js +7 -1
  75. package/lib/Types/Contact.d.ts +24 -0
  76. package/lib/Types/Events.d.ts +237 -0
  77. package/lib/Types/Events.js +1 -0
  78. package/lib/Types/GroupMetadata.d.ts +67 -0
  79. package/lib/Types/Label.d.ts +47 -0
  80. package/lib/Types/Label.js +1 -3
  81. package/lib/Types/LabelAssociation.d.ts +30 -0
  82. package/lib/Types/LabelAssociation.js +1 -3
  83. package/lib/Types/Message.d.ts +305 -0
  84. package/lib/Types/Message.js +9 -5
  85. package/lib/Types/MexUpdates.js +11 -0
  86. package/lib/Types/Newsletter.d.ts +135 -0
  87. package/lib/Types/Newsletter.js +36 -11
  88. package/lib/Types/Product.d.ts +79 -0
  89. package/lib/Types/Signal.d.ts +76 -0
  90. package/lib/Types/Signal.js +1 -0
  91. package/lib/Types/Socket.d.ts +133 -0
  92. package/lib/Types/Socket.js +1 -0
  93. package/lib/Types/State.d.ts +39 -0
  94. package/lib/Types/State.js +12 -0
  95. package/lib/Types/USync.d.ts +26 -0
  96. package/lib/Types/USync.js +1 -0
  97. package/lib/Types/index.d.ts +65 -0
  98. package/lib/Types/index.js +14 -14
  99. package/lib/Utils/audioToBuffer.js +31 -0
  100. package/lib/Utils/auth-utils.d.ts +19 -0
  101. package/lib/Utils/auth-utils.js +222 -123
  102. package/lib/Utils/baileys-event-stream.js +60 -0
  103. package/lib/Utils/bridge-runtime.d.ts +1 -0
  104. package/lib/Utils/bridge-runtime.js +14 -0
  105. package/lib/Utils/browser-utils.d.ts +4 -0
  106. package/lib/Utils/browser-utils.js +38 -29
  107. package/lib/Utils/business.d.ts +23 -0
  108. package/lib/Utils/business.js +54 -48
  109. package/lib/Utils/chat-utils.d.ts +70 -0
  110. package/lib/Utils/chat-utils.js +284 -189
  111. package/lib/Utils/crypto.d.ts +37 -0
  112. package/lib/Utils/crypto.js +16 -41
  113. package/lib/Utils/decode-wa-message.d.ts +48 -0
  114. package/lib/Utils/decode-wa-message.js +128 -48
  115. package/lib/Utils/event-buffer.d.ts +34 -0
  116. package/lib/Utils/event-buffer.js +124 -62
  117. package/lib/Utils/generics.d.ts +91 -0
  118. package/lib/Utils/generics.js +154 -138
  119. package/lib/Utils/history.d.ts +22 -0
  120. package/lib/Utils/history.js +77 -34
  121. package/lib/Utils/identity-change-handler.d.ts +37 -0
  122. package/lib/Utils/identity-change-handler.js +54 -0
  123. package/lib/Utils/index.d.ts +22 -0
  124. package/lib/Utils/index.js +32 -19
  125. package/lib/Utils/link-preview.d.ts +21 -0
  126. package/lib/Utils/link-preview.js +12 -17
  127. package/lib/Utils/logger.d.ts +13 -0
  128. package/lib/Utils/lt-hash.d.ts +8 -0
  129. package/lib/Utils/lt-hash.js +2 -43
  130. package/lib/Utils/make-mutex.d.ts +9 -0
  131. package/lib/Utils/make-mutex.js +21 -27
  132. package/lib/Utils/message-retry-manager.d.ts +110 -0
  133. package/lib/Utils/message-retry-manager.js +143 -45
  134. package/lib/Utils/messages-media.d.ts +130 -0
  135. package/lib/Utils/messages-media.js +429 -502
  136. package/lib/Utils/messages-newsletter.d.ts +84 -0
  137. package/lib/Utils/messages-newsletter.js +295 -0
  138. package/lib/Utils/messages.d.ts +92 -0
  139. package/lib/Utils/messages.js +1025 -674
  140. package/lib/Utils/noise-handler.d.ts +20 -0
  141. package/lib/Utils/noise-handler.js +145 -91
  142. package/lib/Utils/pre-key-manager.d.ts +28 -0
  143. package/lib/Utils/pre-key-manager.js +112 -0
  144. package/lib/Utils/process-message.d.ts +60 -0
  145. package/lib/Utils/process-message.js +316 -184
  146. package/lib/Utils/reporting-utils.d.ts +11 -0
  147. package/lib/Utils/reporting-utils.js +262 -0
  148. package/lib/Utils/resolve-jid.d.ts +43 -0
  149. package/lib/Utils/resolve-jid.js +95 -0
  150. package/lib/Utils/rust-bridge-shim.d.ts +22 -0
  151. package/lib/Utils/rust-bridge-shim.js +70 -0
  152. package/lib/Utils/serial-task-queue.js +29 -0
  153. package/lib/Utils/signal.d.ts +34 -0
  154. package/lib/Utils/signal.js +56 -39
  155. package/lib/Utils/streamToBuffer.js +17 -0
  156. package/lib/Utils/sync-action-utils.d.ts +19 -0
  157. package/lib/Utils/sync-action-utils.js +52 -0
  158. package/lib/Utils/tc-token-utils.d.ts +12 -0
  159. package/lib/Utils/tc-token-utils.js +20 -0
  160. package/lib/Utils/use-mongo-file-auth-state.js +71 -0
  161. package/lib/Utils/use-multi-file-auth-state.d.ts +13 -0
  162. package/lib/Utils/use-multi-file-auth-state.js +11 -12
  163. package/lib/Utils/use-single-file-auth-state.js +73 -0
  164. package/lib/Utils/validate-connection.d.ts +11 -0
  165. package/lib/Utils/validate-connection.js +59 -82
  166. package/lib/Utils/wileys-event-stream.js +1 -61
  167. package/lib/WABinary/constants.d.ts +28 -0
  168. package/lib/WABinary/decode.d.ts +7 -0
  169. package/lib/WABinary/decode.js +39 -4
  170. package/lib/WABinary/encode.d.ts +3 -0
  171. package/lib/WABinary/encode.js +17 -11
  172. package/lib/WABinary/generic-utils.d.ts +15 -0
  173. package/lib/WABinary/generic-utils.js +46 -18
  174. package/lib/WABinary/index.d.ts +6 -0
  175. package/lib/WABinary/index.js +9 -5
  176. package/lib/WABinary/jid-utils.d.ts +48 -0
  177. package/lib/WABinary/jid-utils.js +67 -37
  178. package/lib/WABinary/types.d.ts +19 -0
  179. package/lib/WABinary/types.js +34 -0
  180. package/lib/WAM/BinaryInfo.d.ts +9 -0
  181. package/lib/WAM/constants.d.ts +40 -0
  182. package/lib/WAM/constants.js +19183 -11678
  183. package/lib/WAM/encode.d.ts +3 -0
  184. package/lib/WAM/encode.js +15 -17
  185. package/lib/WAM/index.d.ts +4 -0
  186. package/lib/WAM/index.js +3 -3
  187. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +10 -0
  188. package/lib/WAUSync/Protocols/USyncContactProtocol.js +6 -6
  189. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +23 -0
  190. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +9 -9
  191. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +13 -0
  192. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +6 -6
  193. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +13 -0
  194. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +7 -8
  195. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +26 -0
  196. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +18 -17
  197. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +10 -0
  198. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +11 -3
  199. package/lib/WAUSync/Protocols/index.d.ts +5 -0
  200. package/lib/WAUSync/Protocols/index.js +6 -4
  201. package/lib/WAUSync/USyncQuery.d.ts +29 -0
  202. package/lib/WAUSync/USyncQuery.js +38 -30
  203. package/lib/WAUSync/USyncUser.d.ts +13 -0
  204. package/lib/WAUSync/index.d.ts +4 -0
  205. package/lib/WAUSync/index.js +3 -3
  206. package/lib/index.d.ts +12 -0
  207. package/lib/index.js +3 -5
  208. package/package.json +7 -4
  209. package/LICENSE +0 -21
@@ -4,46 +4,45 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.makeChatsSocket = void 0;
7
- const boom_1 = require("@hapi/boom");
8
7
  const node_cache_1 = __importDefault(require("@cacheable/node-cache"));
9
- const WAProto_1 = require("../../WAProto");
10
- const Defaults_1 = require("../Defaults");
11
- const Types_1 = require("../Types");
12
- const Utils_1 = require("../Utils");
13
- const make_mutex_1 = require("../Utils/make-mutex");
14
- const process_message_1 = __importDefault(require("../Utils/process-message"));
15
- const WABinary_1 = require("../WABinary");
16
- const WAUSync_1 = require("../WAUSync");
17
- const usync_1 = require("./usync");
18
- const chalk = require('chalk');
8
+ const boom_1 = require("@hapi/boom");
9
+ const index_js_1 = require("../../WAProto/index.js");
10
+ const index_js_2 = require("../Defaults/index.js");
11
+ const index_js_3 = require("../Types/index.js");
12
+ const State_js_1 = require("../Types/State.js");
13
+ const index_js_4 = require("../Utils/index.js");
14
+ const make_mutex_js_1 = require("../Utils/make-mutex.js");
15
+ const process_message_js_1 = __importDefault(require("../Utils/process-message.js"));
16
+ const tc_token_utils_js_1 = require("../Utils/tc-token-utils.js");
17
+ const index_js_5 = require("../WABinary/index.js");
18
+ const index_js_6 = require("../WAUSync/index.js");
19
+ const socket_js_1 = require("./socket.js");
19
20
  const MAX_SYNC_ATTEMPTS = 2;
20
- const SyncState = {
21
- Connecting: 'connecting',
22
- AwaitingInitialSync: 'awaiting_initial_sync',
23
- Syncing: 'syncing',
24
- Online: 'online'
25
- };
26
21
  const makeChatsSocket = (config) => {
27
- const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, } = config;
28
- const sock = (0, usync_1.makeUSyncSocket)(config);
29
- const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, } = sock;
22
+ const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, getMessage } = config;
23
+ const sock = (0, socket_js_1.makeSocket)(config);
24
+ const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, sendUnifiedSession } = sock;
30
25
  let privacySettings;
31
- let syncState = SyncState.Connecting;
32
- let needToFlushWithAppStateSync = false;
33
- let pendingAppStateSync = false;
26
+ let syncState = State_js_1.SyncState.Connecting;
27
+ /** this mutex ensures that messages are processed in order */
28
+ const messageMutex = (0, make_mutex_js_1.makeMutex)();
29
+ /** this mutex ensures that receipts are processed in order */
30
+ const receiptMutex = (0, make_mutex_js_1.makeMutex)();
31
+ /** this mutex ensures that app state patches are processed in order */
32
+ const appStatePatchMutex = (0, make_mutex_js_1.makeMutex)();
33
+ /** this mutex ensures that notifications are processed in order */
34
+ const notificationMutex = (0, make_mutex_js_1.makeMutex)();
35
+ // Timeout for AwaitingInitialSync state
34
36
  let awaitingSyncTimeout;
35
- const processingMutex = (0, make_mutex_1.makeMutex)();
36
- const placeholderResendCache = config.placeholderResendCache || new node_cache_1.default({
37
- stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY,
38
- useClones: false
39
- });
40
- const receivedMessageDedupCache = new node_cache_1.default({
41
- stdTTL: 3 * 60,
42
- useClones: false
43
- });
37
+ const placeholderResendCache = config.placeholderResendCache ||
38
+ new node_cache_1.default({
39
+ stdTTL: index_js_2.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
40
+ useClones: false
41
+ });
44
42
  if (!config.placeholderResendCache) {
45
43
  config.placeholderResendCache = placeholderResendCache;
46
44
  }
45
+ /** helper function to fetch the given app state sync key */
47
46
  const getAppStateSyncKey = async (keyId) => {
48
47
  const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId]);
49
48
  return key;
@@ -54,26 +53,26 @@ const makeChatsSocket = (config) => {
54
53
  tag: 'iq',
55
54
  attrs: {
56
55
  xmlns: 'privacy',
57
- to: WABinary_1.S_WHATSAPP_NET,
56
+ to: index_js_5.S_WHATSAPP_NET,
58
57
  type: 'get'
59
58
  },
60
- content: [
61
- { tag: 'privacy', attrs: {} }
62
- ]
59
+ content: [{ tag: 'privacy', attrs: {} }]
63
60
  });
64
- privacySettings = (0, WABinary_1.reduceBinaryNodeToDictionary)(content === null || content === void 0 ? void 0 : content[0], 'category');
61
+ privacySettings = (0, index_js_5.reduceBinaryNodeToDictionary)(content?.[0], 'category');
65
62
  }
66
63
  return privacySettings;
67
64
  };
65
+ /** helper function to run a privacy IQ query */
68
66
  const privacyQuery = async (name, value) => {
69
67
  await query({
70
68
  tag: 'iq',
71
69
  attrs: {
72
70
  xmlns: 'privacy',
73
- to: WABinary_1.S_WHATSAPP_NET,
71
+ to: index_js_5.S_WHATSAPP_NET,
74
72
  type: 'set'
75
73
  },
76
- content: [{
74
+ content: [
75
+ {
77
76
  tag: 'privacy',
78
77
  attrs: {},
79
78
  content: [
@@ -82,7 +81,8 @@ const makeChatsSocket = (config) => {
82
81
  attrs: { name, value }
83
82
  }
84
83
  ]
85
- }]
84
+ }
85
+ ]
86
86
  });
87
87
  };
88
88
  const updateMessagesPrivacy = async (value) => {
@@ -109,23 +109,22 @@ const makeChatsSocket = (config) => {
109
109
  const updateGroupsAddPrivacy = async (value) => {
110
110
  await privacyQuery('groupadd', value);
111
111
  };
112
- const updateDisableLinkPreviewsPrivacy = async (isPreviewsDisabled) => {
113
- return chatModify({ disableLinkPreviews: { isPreviewsDisabled } }, '');
114
- };
115
112
  const updateDefaultDisappearingMode = async (duration) => {
116
113
  await query({
117
114
  tag: 'iq',
118
115
  attrs: {
119
116
  xmlns: 'disappearing_mode',
120
- to: WABinary_1.S_WHATSAPP_NET,
117
+ to: index_js_5.S_WHATSAPP_NET,
121
118
  type: 'set'
122
119
  },
123
- content: [{
120
+ content: [
121
+ {
124
122
  tag: 'disappearing_mode',
125
123
  attrs: {
126
124
  duration: duration.toString()
127
125
  }
128
- }]
126
+ }
127
+ ]
129
128
  });
130
129
  };
131
130
  const getBotListV2 = async () => {
@@ -133,21 +132,23 @@ const makeChatsSocket = (config) => {
133
132
  tag: 'iq',
134
133
  attrs: {
135
134
  xmlns: 'bot',
136
- to: WABinary_1.S_WHATSAPP_NET,
135
+ to: index_js_5.S_WHATSAPP_NET,
137
136
  type: 'get'
138
137
  },
139
- content: [{
138
+ content: [
139
+ {
140
140
  tag: 'bot',
141
141
  attrs: {
142
142
  v: '2'
143
143
  }
144
- }]
144
+ }
145
+ ]
145
146
  });
146
- const botNode = (0, WABinary_1.getBinaryNodeChild)(resp, 'bot');
147
+ const botNode = (0, index_js_5.getBinaryNodeChild)(resp, 'bot');
147
148
  const botList = [];
148
- for (const section of (0, WABinary_1.getBinaryNodeChildren)(botNode, 'section')) {
149
+ for (const section of (0, index_js_5.getBinaryNodeChildren)(botNode, 'section')) {
149
150
  if (section.attrs.type === 'all') {
150
- for (const bot of (0, WABinary_1.getBinaryNodeChildren)(section, 'bot')) {
151
+ for (const bot of (0, index_js_5.getBinaryNodeChildren)(section, 'bot')) {
151
152
  botList.push({
152
153
  jid: bot.attrs.jid,
153
154
  personaId: bot.attrs['persona_id']
@@ -157,24 +158,29 @@ const makeChatsSocket = (config) => {
157
158
  }
158
159
  return botList;
159
160
  };
160
- const onWhatsApp = async (...jids) => {
161
- const usyncQuery = new WAUSync_1.USyncQuery()
162
- .withContactProtocol()
163
- .withLIDProtocol();
164
- for (const jid of jids) {
165
- const phone = `+${jid.replace('+', '').split('@')[0].split(':')[0]}`;
166
- usyncQuery.withUser(new WAUSync_1.USyncUser().withPhone(phone));
167
- }
168
- const results = await sock.executeUSyncQuery(usyncQuery);
169
- if (results) {
170
- return results.list.filter((a) => !!a.contact).map(({ contact, id, lid }) => ({ jid: id, exists: contact, lid }));
161
+ const getLidUser = async (jid) => {
162
+ if (!jid)
163
+ throw new boom_1.Boom('Please input a jid user');
164
+ if (!jid.endsWith('@s.whatsapp.net') && !jid.endsWith('@lid')) {
165
+ throw new boom_1.Boom('Invalid JID: Not a user JID!');
171
166
  }
167
+ const targetJid = jid.includes('@') ? jid : `${jid}@s.whatsapp.net`;
168
+ const usyncQuery = new index_js_6.USyncQuery();
169
+ usyncQuery.protocols.push({
170
+ name: 'lid',
171
+ getQueryElement: () => ({ tag: 'lid', attrs: {}, content: undefined }),
172
+ getUserElement: () => null,
173
+ parser: (node) => node.attrs.val
174
+ });
175
+ usyncQuery.users.push({ id: targetJid });
176
+ const result = await sock.executeUSyncQuery(usyncQuery);
177
+ if (result)
178
+ return result.list;
172
179
  };
173
180
  const fetchStatus = async (...jids) => {
174
- const usyncQuery = new WAUSync_1.USyncQuery()
175
- .withStatusProtocol();
181
+ const usyncQuery = new index_js_6.USyncQuery().withStatusProtocol();
176
182
  for (const jid of jids) {
177
- usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid));
183
+ usyncQuery.withUser(new index_js_6.USyncUser().withId(jid));
178
184
  }
179
185
  const result = await sock.executeUSyncQuery(usyncQuery);
180
186
  if (result) {
@@ -182,32 +188,35 @@ const makeChatsSocket = (config) => {
182
188
  }
183
189
  };
184
190
  const fetchDisappearingDuration = async (...jids) => {
185
- const usyncQuery = new WAUSync_1.USyncQuery()
186
- .withDisappearingModeProtocol();
191
+ const usyncQuery = new index_js_6.USyncQuery().withDisappearingModeProtocol();
187
192
  for (const jid of jids) {
188
- usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid));
193
+ usyncQuery.withUser(new index_js_6.USyncUser().withId(jid));
189
194
  }
190
195
  const result = await sock.executeUSyncQuery(usyncQuery);
191
196
  if (result) {
192
197
  return result.list;
193
198
  }
194
199
  };
200
+ /** update the profile picture for yourself or a group */
195
201
  const updateProfilePicture = async (jid, content, dimensions) => {
196
202
  let targetJid;
197
203
  if (!jid) {
198
204
  throw new boom_1.Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
199
205
  }
200
- if ((0, WABinary_1.jidNormalizedUser)(jid) !== (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id)) {
201
- targetJid = (0, WABinary_1.jidNormalizedUser)(jid);
206
+ if ((0, index_js_5.jidNormalizedUser)(jid) !== (0, index_js_5.jidNormalizedUser)(authState.creds.me.id)) {
207
+ targetJid = (0, index_js_5.jidNormalizedUser)(jid); // in case it is someone other than us
208
+ }
209
+ else {
210
+ targetJid = undefined;
202
211
  }
203
- const { img } = await (0, Utils_1.generateProfilePicture)(content, dimensions);
212
+ const { img } = await (0, index_js_4.generateProfilePicture)(content, dimensions);
204
213
  await query({
205
214
  tag: 'iq',
206
215
  attrs: {
207
- target: targetJid,
208
- to: WABinary_1.S_WHATSAPP_NET,
216
+ to: index_js_5.S_WHATSAPP_NET,
209
217
  type: 'set',
210
- xmlns: 'w:profile:picture'
218
+ xmlns: 'w:profile:picture',
219
+ ...(targetJid ? { target: targetJid } : {})
211
220
  },
212
221
  content: [
213
222
  {
@@ -218,29 +227,34 @@ const makeChatsSocket = (config) => {
218
227
  ]
219
228
  });
220
229
  };
230
+ /** remove the profile picture for yourself or a group */
221
231
  const removeProfilePicture = async (jid) => {
222
232
  let targetJid;
223
233
  if (!jid) {
224
234
  throw new boom_1.Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
225
235
  }
226
- if ((0, WABinary_1.jidNormalizedUser)(jid) !== (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id)) {
227
- targetJid = (0, WABinary_1.jidNormalizedUser)(jid);
236
+ if ((0, index_js_5.jidNormalizedUser)(jid) !== (0, index_js_5.jidNormalizedUser)(authState.creds.me.id)) {
237
+ targetJid = (0, index_js_5.jidNormalizedUser)(jid); // in case it is someone other than us
238
+ }
239
+ else {
240
+ targetJid = undefined;
228
241
  }
229
242
  await query({
230
243
  tag: 'iq',
231
244
  attrs: {
232
- target: targetJid,
233
- to: WABinary_1.S_WHATSAPP_NET,
245
+ to: index_js_5.S_WHATSAPP_NET,
234
246
  type: 'set',
235
- xmlns: 'w:profile:picture'
247
+ xmlns: 'w:profile:picture',
248
+ ...(targetJid ? { target: targetJid } : {})
236
249
  }
237
250
  });
238
251
  };
252
+ /** update the profile status for yourself */
239
253
  const updateProfileStatus = async (status) => {
240
254
  await query({
241
255
  tag: 'iq',
242
256
  attrs: {
243
- to: WABinary_1.S_WHATSAPP_NET,
257
+ to: index_js_5.S_WHATSAPP_NET,
244
258
  type: 'set',
245
259
  xmlns: 'status'
246
260
  },
@@ -261,35 +275,50 @@ const makeChatsSocket = (config) => {
261
275
  tag: 'iq',
262
276
  attrs: {
263
277
  xmlns: 'blocklist',
264
- to: WABinary_1.S_WHATSAPP_NET,
278
+ to: index_js_5.S_WHATSAPP_NET,
265
279
  type: 'get'
266
280
  }
267
281
  });
268
- const listNode = (0, WABinary_1.getBinaryNodeChild)(result, 'list');
269
- return (0, WABinary_1.getBinaryNodeChildren)(listNode, 'item')
270
- .map(n => n.attrs.jid);
282
+ const listNode = (0, index_js_5.getBinaryNodeChild)(result, 'list');
283
+ return (0, index_js_5.getBinaryNodeChildren)(listNode, 'item').map(n => n.attrs.jid);
271
284
  };
272
285
  const updateBlockStatus = async (jid, action) => {
286
+ jid = (0, index_js_5.jidNormalizedUser)(jid);
287
+ // Jika input adalah LID, resolve ke PN dulu
288
+ if (jid.endsWith('@lid')) {
289
+ try {
290
+ const pn = await signalRepository?.lidMapping?.getPNForLID?.(jid).catch(() => null);
291
+ if (pn)
292
+ jid = (0, index_js_5.jidNormalizedUser)(pn);
293
+ }
294
+ catch { }
295
+ }
296
+ const dhash = String(Date.now());
297
+ const itemAttrs = {
298
+ dhash,
299
+ action,
300
+ jid, // selalu PN
301
+ };
302
+ // Block: tambah pn_jid juga
303
+ if (action === 'block') {
304
+ itemAttrs.pn_jid = jid;
305
+ }
273
306
  await query({
274
307
  tag: 'iq',
275
308
  attrs: {
276
309
  xmlns: 'blocklist',
277
- to: WABinary_1.S_WHATSAPP_NET,
310
+ to: index_js_5.S_WHATSAPP_NET,
278
311
  type: 'set'
279
312
  },
280
313
  content: [
281
314
  {
282
315
  tag: 'item',
283
- attrs: {
284
- action,
285
- jid
286
- }
316
+ attrs: itemAttrs
287
317
  }
288
318
  ]
289
319
  });
290
320
  };
291
321
  const getBusinessProfile = async (jid) => {
292
- var _a, _b, _c, _d, _e, _f, _g;
293
322
  const results = await query({
294
323
  tag: 'iq',
295
324
  attrs: {
@@ -297,38 +326,42 @@ const makeChatsSocket = (config) => {
297
326
  xmlns: 'w:biz',
298
327
  type: 'get'
299
328
  },
300
- content: [{
329
+ content: [
330
+ {
301
331
  tag: 'business_profile',
302
332
  attrs: { v: '244' },
303
- content: [{
333
+ content: [
334
+ {
304
335
  tag: 'profile',
305
336
  attrs: { jid }
306
- }]
307
- }]
337
+ }
338
+ ]
339
+ }
340
+ ]
308
341
  });
309
- const profileNode = (0, WABinary_1.getBinaryNodeChild)(results, 'business_profile');
310
- const profiles = (0, WABinary_1.getBinaryNodeChild)(profileNode, 'profile');
342
+ const profileNode = (0, index_js_5.getBinaryNodeChild)(results, 'business_profile');
343
+ const profiles = (0, index_js_5.getBinaryNodeChild)(profileNode, 'profile');
311
344
  if (profiles) {
312
- const address = (0, WABinary_1.getBinaryNodeChild)(profiles, 'address');
313
- const description = (0, WABinary_1.getBinaryNodeChild)(profiles, 'description');
314
- const website = (0, WABinary_1.getBinaryNodeChild)(profiles, 'website');
315
- const email = (0, WABinary_1.getBinaryNodeChild)(profiles, 'email');
316
- const category = (0, WABinary_1.getBinaryNodeChild)((0, WABinary_1.getBinaryNodeChild)(profiles, 'categories'), 'category');
317
- const businessHours = (0, WABinary_1.getBinaryNodeChild)(profiles, 'business_hours');
345
+ const address = (0, index_js_5.getBinaryNodeChild)(profiles, 'address');
346
+ const description = (0, index_js_5.getBinaryNodeChild)(profiles, 'description');
347
+ const website = (0, index_js_5.getBinaryNodeChild)(profiles, 'website');
348
+ const email = (0, index_js_5.getBinaryNodeChild)(profiles, 'email');
349
+ const category = (0, index_js_5.getBinaryNodeChild)((0, index_js_5.getBinaryNodeChild)(profiles, 'categories'), 'category');
350
+ const businessHours = (0, index_js_5.getBinaryNodeChild)(profiles, 'business_hours');
318
351
  const businessHoursConfig = businessHours
319
- ? (0, WABinary_1.getBinaryNodeChildren)(businessHours, 'business_hours_config')
352
+ ? (0, index_js_5.getBinaryNodeChildren)(businessHours, 'business_hours_config')
320
353
  : undefined;
321
- const websiteStr = (_a = website === null || website === void 0 ? void 0 : website.content) === null || _a === void 0 ? void 0 : _a.toString();
354
+ const websiteStr = website?.content?.toString();
322
355
  return {
323
- wid: (_b = profiles.attrs) === null || _b === void 0 ? void 0 : _b.jid,
324
- address: (_c = address === null || address === void 0 ? void 0 : address.content) === null || _c === void 0 ? void 0 : _c.toString(),
325
- description: ((_d = description === null || description === void 0 ? void 0 : description.content) === null || _d === void 0 ? void 0 : _d.toString()) || '',
356
+ wid: profiles.attrs?.jid,
357
+ address: address?.content?.toString(),
358
+ description: description?.content?.toString() || '',
326
359
  website: websiteStr ? [websiteStr] : [],
327
- email: (_e = email === null || email === void 0 ? void 0 : email.content) === null || _e === void 0 ? void 0 : _e.toString(),
328
- category: (_f = category === null || category === void 0 ? void 0 : category.content) === null || _f === void 0 ? void 0 : _f.toString(),
329
- 'business_hours': {
330
- timezone: (_g = businessHours === null || businessHours === void 0 ? void 0 : businessHours.attrs) === null || _g === void 0 ? void 0 : _g.timezone,
331
- 'business_config': businessHoursConfig === null || businessHoursConfig === void 0 ? void 0 : businessHoursConfig.map(({ attrs }) => attrs)
360
+ email: email?.content?.toString(),
361
+ category: category?.content?.toString(),
362
+ business_hours: {
363
+ timezone: businessHours?.attrs?.timezone,
364
+ business_config: businessHoursConfig?.map(({ attrs }) => attrs)
332
365
  }
333
366
  };
334
367
  }
@@ -338,17 +371,17 @@ const makeChatsSocket = (config) => {
338
371
  await sendNode({
339
372
  tag: 'iq',
340
373
  attrs: {
341
- to: WABinary_1.S_WHATSAPP_NET,
374
+ to: index_js_5.S_WHATSAPP_NET,
342
375
  type: 'set',
343
376
  xmlns: 'urn:xmpp:whatsapp:dirty',
344
- id: generateMessageTag(),
377
+ id: generateMessageTag()
345
378
  },
346
379
  content: [
347
380
  {
348
381
  tag: 'clean',
349
382
  attrs: {
350
383
  type,
351
- ...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null),
384
+ ...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null)
352
385
  }
353
386
  }
354
387
  ]
@@ -357,17 +390,31 @@ const makeChatsSocket = (config) => {
357
390
  const newAppStateChunkHandler = (isInitialSync) => {
358
391
  return {
359
392
  onMutation(mutation) {
360
- (0, Utils_1.processSyncAction)(mutation, ev, authState.creds.me, isInitialSync ? { accountSettings: authState.creds.accountSettings } : undefined, logger);
393
+ (0, index_js_4.processSyncAction)(mutation, ev, authState.creds.me, isInitialSync ? { accountSettings: authState.creds.accountSettings } : undefined, logger);
361
394
  }
362
395
  };
363
396
  };
364
397
  const resyncAppState = ev.createBufferedFunction(async (collections, isInitialSync) => {
398
+ const appStateSyncKeyCache = new Map();
399
+ const getCachedAppStateSyncKey = async (keyId) => {
400
+ if (appStateSyncKeyCache.has(keyId)) {
401
+ return appStateSyncKeyCache.get(keyId) ?? undefined;
402
+ }
403
+ const key = await getAppStateSyncKey(keyId);
404
+ appStateSyncKeyCache.set(keyId, key ?? null);
405
+ return key;
406
+ };
407
+ // we use this to determine which events to fire
408
+ // otherwise when we resync from scratch -- all notifications will fire
365
409
  const initialVersionMap = {};
366
410
  const globalMutationMap = {};
367
411
  await authState.keys.transaction(async () => {
368
- var _a;
369
412
  const collectionsToHandle = new Set(collections);
413
+ // in case something goes wrong -- ensure we don't enter a loop that cannot be exited from
370
414
  const attemptsMap = {};
415
+ // keep executing till all collections are done
416
+ // sometimes a single patch request will not return all the patches (God knows why)
417
+ // so we fetch till they're all done (this is determined by the "has_more_patches" flag)
371
418
  while (collectionsToHandle.size) {
372
419
  const states = {};
373
420
  const nodes = [];
@@ -380,7 +427,7 @@ const makeChatsSocket = (config) => {
380
427
  }
381
428
  }
382
429
  else {
383
- state = (0, Utils_1.newLTHashState)();
430
+ state = (0, index_js_4.newLTHashState)();
384
431
  }
385
432
  states[name] = state;
386
433
  logger.info(`resyncing ${name} from v${state.version}`);
@@ -389,14 +436,15 @@ const makeChatsSocket = (config) => {
389
436
  attrs: {
390
437
  name,
391
438
  version: state.version.toString(),
392
- 'return_snapshot': (!state.version).toString()
439
+ // return snapshot if being synced from scratch
440
+ return_snapshot: (!state.version).toString()
393
441
  }
394
442
  });
395
443
  }
396
444
  const result = await query({
397
445
  tag: 'iq',
398
446
  attrs: {
399
- to: WABinary_1.S_WHATSAPP_NET,
447
+ to: index_js_5.S_WHATSAPP_NET,
400
448
  xmlns: 'w:sync:app:state',
401
449
  type: 'set'
402
450
  },
@@ -408,20 +456,22 @@ const makeChatsSocket = (config) => {
408
456
  }
409
457
  ]
410
458
  });
411
- const decoded = await (0, Utils_1.extractSyncdPatches)(result, config === null || config === void 0 ? void 0 : config.options);
459
+ // extract from binary node
460
+ const decoded = await (0, index_js_4.extractSyncdPatches)(result, config?.options);
412
461
  for (const key in decoded) {
413
462
  const name = key;
414
463
  const { patches, hasMorePatches, snapshot } = decoded[name];
415
464
  try {
416
465
  if (snapshot) {
417
- const { state: newState, mutationMap } = await (0, Utils_1.decodeSyncdSnapshot)(name, snapshot, getAppStateSyncKey, initialVersionMap[name], appStateMacVerification.snapshot);
466
+ const { state: newState, mutationMap } = await (0, index_js_4.decodeSyncdSnapshot)(name, snapshot, getCachedAppStateSyncKey, initialVersionMap[name], appStateMacVerification.snapshot);
418
467
  states[name] = newState;
419
468
  Object.assign(globalMutationMap, mutationMap);
420
469
  logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`);
421
470
  await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
422
471
  }
472
+ // only process if there are syncd patches
423
473
  if (patches.length) {
424
- const { state: newState, mutationMap } = await (0, Utils_1.decodePatches)(name, patches, states[name], getAppStateSyncKey, config.options, initialVersionMap[name], logger, appStateMacVerification.patch);
474
+ const { state: newState, mutationMap } = await (0, index_js_4.decodePatches)(name, patches, states[name], getCachedAppStateSyncKey, config.options, initialVersionMap[name], logger, appStateMacVerification.patch);
425
475
  await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
426
476
  logger.info(`synced ${name} to v${newState.version}`);
427
477
  initialVersionMap[name] = newState.version;
@@ -431,60 +481,54 @@ const makeChatsSocket = (config) => {
431
481
  logger.info(`${name} has more patches...`);
432
482
  }
433
483
  else {
484
+ // collection is done with sync
434
485
  collectionsToHandle.delete(name);
435
486
  }
436
487
  }
437
488
  catch (error) {
438
- const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS
439
- || ((_a = error.output) === null || _a === void 0 ? void 0 : _a.statusCode) === 404
440
- || error.name === 'TypeError';
489
+ // if retry attempts overshoot
490
+ // or key not found
491
+ const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS ||
492
+ error.output?.statusCode === 404 ||
493
+ error.name === 'TypeError';
441
494
  logger.info({ name, error: error.stack }, `failed to sync state from version${isIrrecoverableError ? '' : ', removing and trying from scratch'}`);
442
495
  await authState.keys.set({ 'app-state-sync-version': { [name]: null } });
496
+ // increment number of retries
443
497
  attemptsMap[name] = (attemptsMap[name] || 0) + 1;
444
498
  if (isIrrecoverableError) {
499
+ // stop retrying
445
500
  collectionsToHandle.delete(name);
446
501
  }
447
502
  }
448
503
  }
449
504
  }
450
- });
505
+ }, authState?.creds?.me?.id || 'resync-app-state');
451
506
  const { onMutation } = newAppStateChunkHandler(isInitialSync);
452
507
  for (const key in globalMutationMap) {
453
508
  onMutation(globalMutationMap[key]);
454
509
  }
455
510
  });
511
+ /**
512
+ * fetch the profile picture of a user/group
513
+ * type = "preview" for a low res picture
514
+ * type = "image for the high res picture"
515
+ */
456
516
  const profilePictureUrl = async (jid, type = 'preview', timeoutMs) => {
457
- var _a;
458
- jid = (0, WABinary_1.jidNormalizedUser)(jid);
459
- try {
460
- const result = await query({
461
- tag: 'iq',
462
- attrs: {
463
- target: jid,
464
- to: WABinary_1.S_WHATSAPP_NET,
465
- type: 'get',
466
- xmlns: 'w:profile:picture'
467
- },
468
- content: [
469
- { tag: 'picture', attrs: { type, query: 'url' } }
470
- ]
471
- }, timeoutMs);
472
- const child = (0, WABinary_1.getBinaryNodeChild)(result, 'picture');
473
- return (_a = child === null || child === void 0 ? void 0 : child.attrs) === null || _a === void 0 ? void 0 : _a.url;
474
- } catch (error) {
475
- if (error.message?.includes('item-not-found') ||
476
- error.output?.payload?.statusCode === 404 ||
477
- error.statusCode === 404) {
478
- logger.info(chalk.gray(`[INFO] Profile pic not found for ${jid}, using fallback`));
479
- return {
480
- eurl: undefined,
481
- id: jid.split('@')[0],
482
- status: null,
483
- img: null
484
- };
485
- }
486
- throw error;
487
- }
517
+ const baseContent = [{ tag: 'picture', attrs: { type, query: 'url' } }];
518
+ const tcTokenContent = await (0, tc_token_utils_js_1.buildTcTokenFromJid)({ authState, jid, baseContent });
519
+ jid = (0, index_js_5.jidNormalizedUser)(jid);
520
+ const result = await query({
521
+ tag: 'iq',
522
+ attrs: {
523
+ target: jid,
524
+ to: index_js_5.S_WHATSAPP_NET,
525
+ type: 'get',
526
+ xmlns: 'w:profile:picture'
527
+ },
528
+ content: tcTokenContent
529
+ }, timeoutMs);
530
+ const child = (0, index_js_5.getBinaryNodeChild)(result, 'picture');
531
+ return child?.attrs?.url;
488
532
  };
489
533
  const createCallLink = async (type, event, timeoutMs) => {
490
534
  const result = await query({
@@ -501,17 +545,21 @@ const makeChatsSocket = (config) => {
501
545
  }
502
546
  ]
503
547
  }, timeoutMs);
504
- const child = (0, WABinary_1.getBinaryNodeChild)(result, 'link_create');
548
+ const child = (0, index_js_5.getBinaryNodeChild)(result, 'link_create');
505
549
  return child?.attrs?.token;
506
550
  };
507
551
  const sendPresenceUpdate = async (type, toJid) => {
508
552
  const me = authState.creds.me;
509
- if (type === 'available' || type === 'unavailable') {
553
+ const isAvailableType = type === 'available';
554
+ if (isAvailableType || type === 'unavailable') {
510
555
  if (!me.name) {
511
556
  logger.warn('no name present, ignoring presence update request...');
512
557
  return;
513
558
  }
514
- ev.emit('connection.update', { isOnline: type === 'available' });
559
+ ev.emit('connection.update', { isOnline: isAvailableType });
560
+ if (isAvailableType) {
561
+ void sendUnifiedSession();
562
+ }
515
563
  await sendNode({
516
564
  tag: 'presence',
517
565
  attrs: {
@@ -521,13 +569,13 @@ const makeChatsSocket = (config) => {
521
569
  });
522
570
  }
523
571
  else {
524
- const { server } = (0, WABinary_1.jidDecode)(toJid);
572
+ const { server } = (0, index_js_5.jidDecode)(toJid);
525
573
  const isLid = server === 'lid';
526
574
  await sendNode({
527
575
  tag: 'chatstate',
528
576
  attrs: {
529
577
  from: isLid ? me.lid : me.id,
530
- to: toJid,
578
+ to: toJid
531
579
  },
532
580
  content: [
533
581
  {
@@ -538,29 +586,27 @@ const makeChatsSocket = (config) => {
538
586
  });
539
587
  }
540
588
  };
541
- const presenceSubscribe = (toJid, tcToken) => (sendNode({
542
- tag: 'presence',
543
- attrs: {
544
- to: toJid,
545
- id: generateMessageTag(),
546
- type: 'subscribe'
547
- },
548
- content: tcToken
549
- ? [
550
- {
551
- tag: 'tctoken',
552
- attrs: {},
553
- content: tcToken
554
- }
555
- ]
556
- : undefined
557
- }));
589
+ /**
590
+ * @param toJid the jid to subscribe to
591
+ * @param tcToken token for subscription, use if present
592
+ */
593
+ const presenceSubscribe = async (toJid) => {
594
+ const tcTokenContent = await (0, tc_token_utils_js_1.buildTcTokenFromJid)({ authState, jid: toJid });
595
+ return sendNode({
596
+ tag: 'presence',
597
+ attrs: {
598
+ to: toJid,
599
+ id: generateMessageTag(),
600
+ type: 'subscribe'
601
+ },
602
+ content: tcTokenContent
603
+ });
604
+ };
558
605
  const handlePresenceUpdate = ({ tag, attrs, content }) => {
559
- var _a;
560
606
  let presence;
561
607
  const jid = attrs.from;
562
608
  const participant = attrs.participant || attrs.from;
563
- if (shouldIgnoreJid(jid) && jid != '@s.whatsapp.net') {
609
+ if (shouldIgnoreJid(jid) && jid !== index_js_5.S_WHATSAPP_NET) {
564
610
  return;
565
611
  }
566
612
  if (tag === 'presence') {
@@ -575,7 +621,7 @@ const makeChatsSocket = (config) => {
575
621
  if (type === 'paused') {
576
622
  type = 'available';
577
623
  }
578
- if (((_a = firstChild.attrs) === null || _a === void 0 ? void 0 : _a.media) === 'audio') {
624
+ if (firstChild.attrs?.media === 'audio') {
579
625
  type = 'recording';
580
626
  }
581
627
  presence = { lastKnownPresence: type };
@@ -595,18 +641,18 @@ const makeChatsSocket = (config) => {
595
641
  }
596
642
  let initial;
597
643
  let encodeResult;
598
- await processingMutex.mutex(async () => {
644
+ await appStatePatchMutex.mutex(async () => {
599
645
  await authState.keys.transaction(async () => {
600
646
  logger.debug({ patch: patchCreate }, 'applying app patch');
601
647
  await resyncAppState([name], false);
602
648
  const { [name]: currentSyncVersion } = await authState.keys.get('app-state-sync-version', [name]);
603
- initial = currentSyncVersion || (0, Utils_1.newLTHashState)();
604
- encodeResult = await (0, Utils_1.encodeSyncdPatch)(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey);
649
+ initial = currentSyncVersion || (0, index_js_4.newLTHashState)();
650
+ encodeResult = await (0, index_js_4.encodeSyncdPatch)(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey);
605
651
  const { patch, state } = encodeResult;
606
652
  const node = {
607
653
  tag: 'iq',
608
654
  attrs: {
609
- to: WABinary_1.S_WHATSAPP_NET,
655
+ to: index_js_5.S_WHATSAPP_NET,
610
656
  type: 'set',
611
657
  xmlns: 'w:sync:app:state'
612
658
  },
@@ -620,13 +666,13 @@ const makeChatsSocket = (config) => {
620
666
  attrs: {
621
667
  name,
622
668
  version: (state.version - 1).toString(),
623
- 'return_snapshot': 'false'
669
+ return_snapshot: 'false'
624
670
  },
625
671
  content: [
626
672
  {
627
673
  tag: 'patch',
628
674
  attrs: {},
629
- content: WAProto_1.proto.SyncdPatch.encode(patch).finish()
675
+ content: index_js_1.proto.SyncdPatch.encode(patch).finish()
630
676
  }
631
677
  ]
632
678
  }
@@ -636,48 +682,69 @@ const makeChatsSocket = (config) => {
636
682
  };
637
683
  await query(node);
638
684
  await authState.keys.set({ 'app-state-sync-version': { [name]: state } });
639
- });
685
+ }, authState?.creds?.me?.id || 'app-patch');
640
686
  });
641
687
  if (config.emitOwnEvents) {
642
688
  const { onMutation } = newAppStateChunkHandler(false);
643
- const { mutationMap } = await (0, Utils_1.decodePatches)(name, [{ ...encodeResult.patch, version: { version: encodeResult.state.version }, }], initial, getAppStateSyncKey, config.options, undefined, logger);
689
+ const { mutationMap } = await (0, index_js_4.decodePatches)(name, [{ ...encodeResult.patch, version: { version: encodeResult.state.version } }], initial, getAppStateSyncKey, config.options, undefined, logger);
644
690
  for (const key in mutationMap) {
645
691
  onMutation(mutationMap[key]);
646
692
  }
647
693
  }
648
694
  };
695
+ /** sending non-abt props may fix QR scan fail if server expects */
649
696
  const fetchProps = async () => {
650
- var _a, _b, _c;
697
+ //TODO: implement both protocol 1 and protocol 2 prop fetching, specially for abKey for WM
651
698
  const resultNode = await query({
652
699
  tag: 'iq',
653
700
  attrs: {
654
- to: WABinary_1.S_WHATSAPP_NET,
701
+ to: index_js_5.S_WHATSAPP_NET,
655
702
  xmlns: 'w',
656
- type: 'get',
703
+ type: 'get'
657
704
  },
658
705
  content: [
659
- { tag: 'props', attrs: {
706
+ {
707
+ tag: 'props',
708
+ attrs: {
660
709
  protocol: '2',
661
- hash: ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.lastPropHash) || ''
662
- } }
710
+ hash: authState?.creds?.lastPropHash || ''
711
+ }
712
+ }
663
713
  ]
664
714
  });
665
- const propsNode = (0, WABinary_1.getBinaryNodeChild)(resultNode, 'props');
715
+ const propsNode = (0, index_js_5.getBinaryNodeChild)(resultNode, 'props');
666
716
  let props = {};
667
717
  if (propsNode) {
668
- if ((_b = propsNode.attrs) === null || _b === void 0 ? void 0 : _b.hash) {
669
- authState.creds.lastPropHash = (_c = propsNode === null || propsNode === void 0 ? void 0 : propsNode.attrs) === null || _c === void 0 ? void 0 : _c.hash;
718
+ if (propsNode.attrs?.hash) {
719
+ // on some clients, the hash is returning as undefined
720
+ authState.creds.lastPropHash = propsNode?.attrs?.hash;
670
721
  ev.emit('creds.update', authState.creds);
671
722
  }
672
- props = (0, WABinary_1.reduceBinaryNodeToDictionary)(propsNode, 'prop');
723
+ props = (0, index_js_5.reduceBinaryNodeToDictionary)(propsNode, 'prop');
673
724
  }
674
725
  logger.debug('fetched props');
675
726
  return props;
676
727
  };
728
+ /**
729
+ * modify a chat -- mark unread, read etc.
730
+ * lastMessages must be sorted in reverse chronologically
731
+ * requires the last messages till the last message received; required for archive & unread
732
+ */
677
733
  const chatModify = (mod, jid) => {
678
- const patch = (0, Utils_1.chatModificationToAppPatch)(mod, jid);
734
+ const patch = (0, index_js_4.chatModificationToAppPatch)(mod, jid);
679
735
  return appPatch(patch);
680
736
  };
737
+ /**
738
+ * Enable/Disable link preview privacy, not related to baileys link preview generation
739
+ */
740
+ const updateDisableLinkPreviewsPrivacy = (isPreviewsDisabled) => {
741
+ return chatModify({
742
+ disableLinkPreviews: { isPreviewsDisabled }
743
+ }, '');
744
+ };
745
+ /**
746
+ * Star or Unstar a message
747
+ */
681
748
  const star = (jid, messages, star) => {
682
749
  return chatModify({
683
750
  star: {
@@ -686,15 +753,35 @@ const makeChatsSocket = (config) => {
686
753
  }
687
754
  }, jid);
688
755
  };
756
+ /**
757
+ * Add or Edit Contact
758
+ */
689
759
  const addOrEditContact = (jid, contact) => {
690
- return chatModify({ contact }, jid);
760
+ return chatModify({
761
+ contact
762
+ }, jid);
691
763
  };
764
+ /**
765
+ * Remove Contact
766
+ */
692
767
  const removeContact = (jid) => {
693
- return chatModify({ contact: null }, jid);
768
+ return chatModify({
769
+ contact: null
770
+ }, jid);
694
771
  };
772
+ /**
773
+ * Adds label
774
+ */
695
775
  const addLabel = (jid, labels) => {
696
- return chatModify({ addLabel: { ...labels } }, jid);
776
+ return chatModify({
777
+ addLabel: {
778
+ ...labels
779
+ }
780
+ }, jid);
697
781
  };
782
+ /**
783
+ * Adds label for the chats
784
+ */
698
785
  const addChatLabel = (jid, labelId) => {
699
786
  return chatModify({
700
787
  addChatLabel: {
@@ -702,6 +789,9 @@ const makeChatsSocket = (config) => {
702
789
  }
703
790
  }, jid);
704
791
  };
792
+ /**
793
+ * Removes label for the chat
794
+ */
705
795
  const removeChatLabel = (jid, labelId) => {
706
796
  return chatModify({
707
797
  removeChatLabel: {
@@ -709,6 +799,9 @@ const makeChatsSocket = (config) => {
709
799
  }
710
800
  }, jid);
711
801
  };
802
+ /**
803
+ * Adds label for the message
804
+ */
712
805
  const addMessageLabel = (jid, messageId, labelId) => {
713
806
  return chatModify({
714
807
  addMessageLabel: {
@@ -717,6 +810,9 @@ const makeChatsSocket = (config) => {
717
810
  }
718
811
  }, jid);
719
812
  };
813
+ /**
814
+ * Removes label for the message
815
+ */
720
816
  const removeMessageLabel = (jid, messageId, labelId) => {
721
817
  return chatModify({
722
818
  removeMessageLabel: {
@@ -725,119 +821,149 @@ const makeChatsSocket = (config) => {
725
821
  }
726
822
  }, jid);
727
823
  };
824
+ /**
825
+ * Add or Edit Quick Reply
826
+ */
827
+ const addOrEditQuickReply = (quickReply) => {
828
+ return chatModify({
829
+ quickReply
830
+ }, '');
831
+ };
832
+ /**
833
+ * Remove Quick Reply
834
+ */
835
+ const removeQuickReply = (timestamp) => {
836
+ return chatModify({
837
+ quickReply: { timestamp, deleted: true }
838
+ }, '');
839
+ };
840
+ /**
841
+ * queries need to be fired on connection open
842
+ * help ensure parity with WA Web
843
+ * */
728
844
  const executeInitQueries = async () => {
729
- await Promise.all([
730
- fetchProps(),
731
- fetchBlocklist(),
732
- fetchPrivacySettings(),
733
- ]);
845
+ await Promise.all([fetchProps(), fetchBlocklist(), fetchPrivacySettings()]);
734
846
  };
735
- const canonicalizeUserJid = (jid) => {
736
- if (!jid) {
737
- return jid;
738
- }
739
- if ((0, WABinary_1.isLidUser)(jid)) {
740
- return (0, WABinary_1.lidToJid)(jid);
741
- }
742
- return jid;
743
- };
744
- const extractStanzaId = (msg) => {
745
- var _a, _b;
746
- const topLevelStanzaId = (_a = msg.messageContextInfo) === null || _a === void 0 ? void 0 : _a.stanzaId;
747
- if (topLevelStanzaId) {
748
- return topLevelStanzaId;
749
- }
750
- const messageContextStanzaId = (_b = msg.message) === null || _b === void 0 ? void 0 : _b.messageContextInfo;
751
- if (messageContextStanzaId === null || messageContextStanzaId === void 0 ? void 0 : messageContextStanzaId.stanzaId) {
752
- return messageContextStanzaId.stanzaId;
753
- }
754
- const normalizedContent = (0, Utils_1.normalizeMessageContent)(msg.message);
755
- const contentType = normalizedContent ? (0, Utils_1.getContentType)(normalizedContent) : undefined;
756
- const contentContextStanzaId = contentType
757
- ? normalizedContent[contentType].contextInfo && normalizedContent[contentType].contextInfo.stanzaId
758
- : undefined;
759
- return contentContextStanzaId;
760
- };
761
- const buildMessageDedupKeys = (msg) => {
762
- const remoteJid = canonicalizeUserJid(msg.key.remoteJid);
763
- const participant = canonicalizeUserJid(msg.key.participant);
764
- const stanzaId = extractStanzaId(msg);
765
- const primaryKey = [remoteJid, participant, msg.key.id, msg.key.fromMe ? '1' : '0', stanzaId || ''].join('|');
766
- const keys = [primaryKey];
767
- // fallback alias key to collapse LID->PN duplicate deliveries for the same incoming user message ID
768
- if (!msg.key.fromMe && ((0, WABinary_1.isJidUser)(msg.key.remoteJid) || (0, WABinary_1.isLidUser)(msg.key.remoteJid))) {
769
- keys.push(`incoming-user-id|${msg.key.id}|${stanzaId || ''}`);
770
- }
771
- return keys;
772
- };
773
- const getDedupState = (msg) => msg.messageStubType === WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT
774
- ? 'ciphertext'
775
- : 'final';
776
847
  const upsertMessage = ev.createBufferedFunction(async (msg, type) => {
777
- var _a, _b, _c;
778
- const dedupKeys = buildMessageDedupKeys(msg);
779
- const dedupState = getDedupState(msg);
780
- const previousDedupState = dedupKeys
781
- .map(key => receivedMessageDedupCache.get(key))
782
- .find(state => !!state);
783
- if (previousDedupState === 'final' || (previousDedupState === 'ciphertext' && dedupState === 'ciphertext')) {
784
- logger.debug({ dedupKeys, messageId: msg.key.id, type, dedupState, previousDedupState }, 'skipping duplicate messages.upsert');
785
- return;
848
+ // ── Auto-inject isAdmin, isBotAdmin, metadata ─────────────────────────
849
+ try {
850
+ const remoteJid = msg.key?.remoteJid || '';
851
+ const isGroup = remoteJid.endsWith('@g.us');
852
+ if (isGroup) {
853
+ const _normalizeJid = (jid) => {
854
+ if (!jid)
855
+ return null;
856
+ try {
857
+ return (0, index_js_5.jidNormalizedUser)(jid).split('@')[0];
858
+ }
859
+ catch {
860
+ return String(jid).split('@')[0];
861
+ }
862
+ };
863
+ // Fetch metadata (pakai cache jika tersedia)
864
+ let meta = null;
865
+ try {
866
+ meta = await sock.groupMetadata(remoteJid);
867
+ }
868
+ catch { }
869
+ if (meta && Array.isArray(meta.participants)) {
870
+ msg.metadata = meta;
871
+ const botJid = authState.creds?.me?.id;
872
+ const senderJid = msg.key.fromMe
873
+ ? authState.creds?.me?.id
874
+ : (msg.key.participant || remoteJid);
875
+ const senderNorm = _normalizeJid(senderJid);
876
+ const botNorm = _normalizeJid(botJid);
877
+ // isAdmin
878
+ msg.isAdmin = meta.participants.some(p => {
879
+ const pid = _normalizeJid(p.jid || p.id || p.lid);
880
+ return pid === senderNorm && (p.admin === 'admin' || p.admin === 'superadmin');
881
+ });
882
+ // isBotAdmin: via m.isBotAdmin jika sudah di-set
883
+ let isBotAdmin = typeof msg.isBotAdmin === 'boolean' ? msg.isBotAdmin : false;
884
+ // fallback via owner
885
+ if (!isBotAdmin) {
886
+ const owners = [meta.owner, meta.subjectOwner, meta.ownerPn]
887
+ .filter(Boolean).map(_normalizeJid);
888
+ if (owners.includes(botNorm))
889
+ isBotAdmin = true;
890
+ }
891
+ // fallback via participants
892
+ if (!isBotAdmin) {
893
+ isBotAdmin = meta.participants.some(p => {
894
+ const pid = _normalizeJid(p.jid || p.id || p.lid);
895
+ return pid === botNorm && (p.admin === 'admin' || p.admin === 'superadmin');
896
+ });
897
+ }
898
+ msg.isBotAdmin = isBotAdmin;
899
+ }
900
+ else {
901
+ msg.metadata = {};
902
+ msg.isAdmin = false;
903
+ msg.isBotAdmin = false;
904
+ }
905
+ }
906
+ else {
907
+ msg.metadata = {};
908
+ msg.isAdmin = false;
909
+ msg.isBotAdmin = false;
910
+ }
786
911
  }
912
+ catch { }
913
+ // ─────────────────────────────────────────────────────────────────────
787
914
  ev.emit('messages.upsert', { messages: [msg], type });
788
915
  if (!!msg.pushName) {
789
- let jid = msg.key.fromMe ? authState.creds.me.id : (msg.key.participant || msg.key.remoteJid);
790
- jid = (0, WABinary_1.jidNormalizedUser)(jid);
916
+ let jid = msg.key.fromMe ? authState.creds.me.id : msg.key.participant || msg.key.remoteJid;
917
+ jid = (0, index_js_5.jidNormalizedUser)(jid);
791
918
  if (!msg.key.fromMe) {
792
919
  ev.emit('contacts.update', [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName }]);
793
920
  }
794
- if (msg.key.fromMe && msg.pushName && ((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.name) !== msg.pushName) {
921
+ // update our pushname too
922
+ if (msg.key.fromMe && msg.pushName && authState.creds.me?.name !== msg.pushName) {
795
923
  ev.emit('creds.update', { me: { ...authState.creds.me, name: msg.pushName } });
796
924
  }
797
925
  }
798
- const historyMsg = (0, Utils_1.getHistoryMsg)(msg.message);
926
+ const historyMsg = (0, index_js_4.getHistoryMsg)(msg.message);
799
927
  const shouldProcessHistoryMsg = historyMsg
800
- ? (shouldSyncHistoryMessage(historyMsg)
801
- && Defaults_1.PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType))
928
+ ? shouldSyncHistoryMessage(historyMsg) &&
929
+ index_js_2.PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType)
802
930
  : false;
803
- if (historyMsg && syncState === SyncState.AwaitingInitialSync) {
931
+ // State machine: decide on sync and flush
932
+ if (historyMsg && syncState === State_js_1.SyncState.AwaitingInitialSync) {
804
933
  if (awaitingSyncTimeout) {
805
934
  clearTimeout(awaitingSyncTimeout);
806
935
  awaitingSyncTimeout = undefined;
807
936
  }
808
937
  if (shouldProcessHistoryMsg) {
809
- syncState = SyncState.Syncing;
938
+ syncState = State_js_1.SyncState.Syncing;
810
939
  logger.info('Transitioned to Syncing state');
811
- } else {
812
- syncState = SyncState.Online;
940
+ // Let doAppStateSync handle the final flush after it's done
941
+ }
942
+ else {
943
+ syncState = State_js_1.SyncState.Online;
813
944
  logger.info('History sync skipped, transitioning to Online state and flushing buffer');
814
945
  ev.flush();
815
946
  }
816
947
  }
817
948
  const doAppStateSync = async () => {
818
- if (syncState === SyncState.Syncing) {
949
+ if (syncState === State_js_1.SyncState.Syncing) {
819
950
  logger.info('Doing app state sync');
820
- await resyncAppState(Types_1.ALL_WA_PATCH_NAMES, true);
821
- syncState = SyncState.Online;
951
+ await resyncAppState(index_js_3.ALL_WA_PATCH_NAMES, true);
952
+ // Sync is complete, go online and flush everything
953
+ syncState = State_js_1.SyncState.Online;
822
954
  logger.info('App state sync complete, transitioning to Online state and flushing buffer');
823
955
  ev.flush();
824
956
  const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1;
825
957
  ev.emit('creds.update', { accountSyncCounter });
826
958
  }
827
959
  };
828
- if (historyMsg && !authState.creds.myAppStateKeyId) {
829
- logger.warn('skipping app state sync, as myAppStateKeyId is not set');
830
- pendingAppStateSync = true;
831
- }
832
960
  await Promise.all([
833
961
  (async () => {
834
- if (historyMsg
835
- && authState.creds.myAppStateKeyId) {
836
- pendingAppStateSync = false;
962
+ if (shouldProcessHistoryMsg) {
837
963
  await doAppStateSync();
838
964
  }
839
965
  })(),
840
- (0, process_message_1.default)(msg, {
966
+ (0, process_message_js_1.default)(msg, {
841
967
  signalRepository,
842
968
  shouldProcessHistoryMsg,
843
969
  placeholderResendCache,
@@ -846,22 +972,19 @@ const makeChatsSocket = (config) => {
846
972
  keyStore: authState.keys,
847
973
  logger,
848
974
  options: config.options,
849
- getMessage: config.getMessage,
975
+ getMessage
850
976
  })
851
977
  ]);
852
- if (((_c = (_b = msg.message) === null || _b === void 0 ? void 0 : _b.protocolMessage) === null || _c === void 0 ? void 0 : _c.appStateSyncKeyShare)
853
- && pendingAppStateSync) {
978
+ // If the app state key arrives and we are waiting to sync, trigger the sync now.
979
+ if (msg.message?.protocolMessage?.appStateSyncKeyShare && syncState === State_js_1.SyncState.Syncing) {
980
+ logger.info('App state sync key arrived, triggering app state sync');
854
981
  await doAppStateSync();
855
- pendingAppStateSync = false;
856
- }
857
- for (const key of dedupKeys) {
858
- receivedMessageDedupCache.set(key, dedupState);
859
982
  }
860
983
  });
861
984
  ws.on('CB:presence', handlePresenceUpdate);
862
985
  ws.on('CB:chatstate', handlePresenceUpdate);
863
986
  ws.on('CB:ib,,dirty', async (node) => {
864
- const { attrs } = (0, WABinary_1.getBinaryNodeChild)(node, 'dirty');
987
+ const { attrs } = (0, index_js_5.getBinaryNodeChild)(node, 'dirty');
865
988
  const type = attrs.type;
866
989
  switch (type) {
867
990
  case 'account_sync':
@@ -875,6 +998,7 @@ const makeChatsSocket = (config) => {
875
998
  }
876
999
  break;
877
1000
  case 'groups':
1001
+ // handled in groups.ts
878
1002
  break;
879
1003
  default:
880
1004
  logger.info({ node }, 'received unknown sync');
@@ -882,34 +1006,24 @@ const makeChatsSocket = (config) => {
882
1006
  }
883
1007
  });
884
1008
  ev.on('connection.update', ({ connection, receivedPendingNotifications }) => {
885
- var _a;
886
1009
  if (connection === 'open') {
887
1010
  if (fireInitQueries) {
888
- executeInitQueries()
889
- .catch(error => onUnexpectedError(error, 'init queries'));
1011
+ executeInitQueries().catch(error => onUnexpectedError(error, 'init queries'));
890
1012
  }
891
- sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable')
892
- .catch(error => onUnexpectedError(error, 'presence update requests'));
893
- }
894
- if (receivedPendingNotifications &&
895
- !((_a = authState.creds) === null || _a === void 0 ? void 0 : _a.myAppStateKeyId)) {
896
- ev.buffer();
897
- needToFlushWithAppStateSync = true;
1013
+ sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable').catch(error => onUnexpectedError(error, 'presence update requests'));
898
1014
  }
899
- if (!receivedPendingNotifications || syncState !== SyncState.Connecting) {
1015
+ if (!receivedPendingNotifications || syncState !== State_js_1.SyncState.Connecting) {
900
1016
  return;
901
1017
  }
902
- syncState = SyncState.AwaitingInitialSync;
1018
+ syncState = State_js_1.SyncState.AwaitingInitialSync;
903
1019
  logger.info('Connection is now AwaitingInitialSync, buffering events');
904
1020
  ev.buffer();
905
- const willSyncHistory = shouldSyncHistoryMessage(
906
- WAProto_1.proto.Message.HistorySyncNotification.create({
907
- syncType: WAProto_1.proto.HistorySync.HistorySyncType.RECENT
908
- })
909
- );
1021
+ const willSyncHistory = shouldSyncHistoryMessage(index_js_1.proto.Message.HistorySyncNotification.create({
1022
+ syncType: index_js_1.proto.HistorySync.HistorySyncType.RECENT
1023
+ }));
910
1024
  if (!willSyncHistory) {
911
1025
  logger.info('History sync is disabled by config, not waiting for notification. Transitioning to Online.');
912
- syncState = SyncState.Online;
1026
+ syncState = State_js_1.SyncState.Online;
913
1027
  setTimeout(() => ev.flush(), 0);
914
1028
  return;
915
1029
  }
@@ -918,28 +1032,85 @@ const makeChatsSocket = (config) => {
918
1032
  clearTimeout(awaitingSyncTimeout);
919
1033
  }
920
1034
  awaitingSyncTimeout = setTimeout(() => {
921
- if (syncState === SyncState.AwaitingInitialSync) {
1035
+ if (syncState === State_js_1.SyncState.AwaitingInitialSync) {
1036
+ // TODO: investigate
922
1037
  logger.warn('Timeout in AwaitingInitialSync, forcing state to Online and flushing buffer');
923
- syncState = SyncState.Online;
1038
+ syncState = State_js_1.SyncState.Online;
924
1039
  ev.flush();
925
1040
  }
926
1041
  }, 20000);
927
1042
  });
1043
+ ev.on('lid-mapping.update', async ({ lid, pn }) => {
1044
+ try {
1045
+ await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }]);
1046
+ }
1047
+ catch (error) {
1048
+ logger.warn({ lid, pn, error }, 'Failed to store LID-PN mapping');
1049
+ }
1050
+ });
1051
+ ev.on('groups.upsert', async (groups) => {
1052
+ try {
1053
+ const mappings = [];
1054
+ for (const group of groups) {
1055
+ for (const p of group.participants || []) {
1056
+ const lidJid = p.id?.endsWith('@lid') ? p.id : p.lid;
1057
+ const pnJid = p.phoneNumber?.endsWith('@s.whatsapp.net')
1058
+ ? p.phoneNumber
1059
+ : p.id?.endsWith('@s.whatsapp.net') ? p.id : undefined;
1060
+ if (lidJid && pnJid) {
1061
+ mappings.push({ lid: lidJid, pn: pnJid });
1062
+ }
1063
+ }
1064
+ }
1065
+ if (mappings.length > 0) {
1066
+ await signalRepository.lidMapping.storeLIDPNMappings(mappings);
1067
+ logger.debug({ count: mappings.length }, 'groups.upsert: stored LID-PN mappings from participants');
1068
+ }
1069
+ }
1070
+ catch (error) {
1071
+ logger.warn({ error }, 'groups.upsert: failed to store LID-PN mappings');
1072
+ }
1073
+ });
1074
+ ev.on('groups.update', async (updates) => {
1075
+ try {
1076
+ const mappings = [];
1077
+ for (const update of updates) {
1078
+ for (const p of update.participants || []) {
1079
+ const lidJid = p.id?.endsWith('@lid') ? p.id : p.lid;
1080
+ const pnJid = p.phoneNumber?.endsWith('@s.whatsapp.net')
1081
+ ? p.phoneNumber
1082
+ : p.id?.endsWith('@s.whatsapp.net') ? p.id : undefined;
1083
+ if (lidJid && pnJid) {
1084
+ mappings.push({ lid: lidJid, pn: pnJid });
1085
+ }
1086
+ }
1087
+ }
1088
+ if (mappings.length > 0) {
1089
+ await signalRepository.lidMapping.storeLIDPNMappings(mappings);
1090
+ logger.debug({ count: mappings.length }, 'groups.update: stored LID-PN mappings from participants');
1091
+ }
1092
+ }
1093
+ catch (error) {
1094
+ logger.warn({ error }, 'groups.update: failed to store LID-PN mappings');
1095
+ }
1096
+ });
928
1097
  return {
929
1098
  ...sock,
930
1099
  createCallLink,
931
1100
  getBotListV2,
932
- processingMutex,
1101
+ messageMutex,
1102
+ receiptMutex,
1103
+ appStatePatchMutex,
1104
+ notificationMutex,
933
1105
  fetchPrivacySettings,
934
1106
  upsertMessage,
935
1107
  appPatch,
936
1108
  sendPresenceUpdate,
937
1109
  presenceSubscribe,
938
1110
  profilePictureUrl,
939
- onWhatsApp,
940
1111
  fetchBlocklist,
941
- fetchDisappearingDuration,
942
1112
  fetchStatus,
1113
+ fetchDisappearingDuration,
943
1114
  updateProfilePicture,
944
1115
  removeProfilePicture,
945
1116
  updateProfileStatus,
@@ -966,7 +1137,19 @@ const makeChatsSocket = (config) => {
966
1137
  removeChatLabel,
967
1138
  addMessageLabel,
968
1139
  removeMessageLabel,
969
- star
1140
+ star,
1141
+ addOrEditQuickReply,
1142
+ removeQuickReply,
1143
+ clearMessage: (jid, key, timeStamp) => {
1144
+ return chatModify({
1145
+ delete: true,
1146
+ lastMessages: [{
1147
+ key: key,
1148
+ messageTimestamp: timeStamp
1149
+ }]
1150
+ }, jid);
1151
+ },
1152
+ getLidUser
970
1153
  };
971
1154
  };
972
1155
  exports.makeChatsSocket = makeChatsSocket;