@fer2809fl/baileys 7.0.1 → 7.0.2

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 (273) hide show
  1. package/README.md +259 -595
  2. package/WAProto/WAProto.proto +916 -360
  3. package/WAProto/fix-imports.js +18 -22
  4. package/WAProto/index.d.ts +15471 -8638
  5. package/WAProto/index.js +80576 -45941
  6. package/lib/Defaults/index.d.ts +14 -18
  7. package/lib/Defaults/index.d.ts.map +1 -1
  8. package/lib/Defaults/index.js +110 -115
  9. package/lib/Defaults/index.js.map +1 -1
  10. package/lib/Signal/Group/group_cipher.js.map +1 -1
  11. package/lib/Signal/Group/keyhelper.d.ts.map +1 -1
  12. package/lib/Signal/Group/keyhelper.js.map +1 -1
  13. package/lib/Signal/Group/sender-chain-key.js.map +1 -1
  14. package/lib/Signal/Group/sender-key-message.js.map +1 -1
  15. package/lib/Signal/Group/sender-message-key.js.map +1 -1
  16. package/lib/Signal/libsignal.d.ts.map +1 -1
  17. package/lib/Signal/libsignal.js +17 -45
  18. package/lib/Signal/libsignal.js.map +1 -1
  19. package/lib/Signal/lid-mapping.d.ts +0 -4
  20. package/lib/Signal/lid-mapping.d.ts.map +1 -1
  21. package/lib/Signal/lid-mapping.js +0 -6
  22. package/lib/Signal/lid-mapping.js.map +1 -1
  23. package/lib/Socket/business.d.ts +532 -280
  24. package/lib/Socket/business.d.ts.map +1 -1
  25. package/lib/Socket/business.js +401 -358
  26. package/lib/Socket/chats.d.ts +2 -22
  27. package/lib/Socket/chats.d.ts.map +1 -1
  28. package/lib/Socket/chats.js +43 -314
  29. package/lib/Socket/chats.js.map +1 -1
  30. package/lib/Socket/communities.d.ts +641 -336
  31. package/lib/Socket/communities.d.ts.map +1 -1
  32. package/lib/Socket/communities.js +3 -6
  33. package/lib/Socket/communities.js.map +1 -1
  34. package/lib/Socket/dugong.d.ts +130 -0
  35. package/lib/Socket/dugong.d.ts.map +1 -0
  36. package/lib/Socket/dugong.js +772 -0
  37. package/lib/Socket/dugong.js.map +1 -0
  38. package/lib/Socket/groups.d.ts +2 -23
  39. package/lib/Socket/groups.d.ts.map +1 -1
  40. package/lib/Socket/groups.js +8 -171
  41. package/lib/Socket/groups.js.map +1 -1
  42. package/lib/Socket/index.d.ts +631 -322
  43. package/lib/Socket/index.d.ts.map +1 -1
  44. package/lib/Socket/index.js +12 -9
  45. package/lib/Socket/index.js.map +1 -1
  46. package/lib/Socket/messages-recv.d.ts +52 -84
  47. package/lib/Socket/messages-recv.d.ts.map +1 -1
  48. package/lib/Socket/messages-recv.js +185 -686
  49. package/lib/Socket/messages-recv.js.map +1 -1
  50. package/lib/Socket/messages-send.d.ts +643 -262
  51. package/lib/Socket/messages-send.d.ts.map +1 -1
  52. package/lib/Socket/messages-send.js +1559 -1359
  53. package/lib/Socket/messages-send.js.map +1 -1
  54. package/lib/Socket/mex.d.ts +0 -1
  55. package/lib/Socket/mex.d.ts.map +1 -1
  56. package/lib/Socket/mex.js +8 -22
  57. package/lib/Socket/mex.js.map +1 -1
  58. package/lib/Socket/native-buttons.js +231 -0
  59. package/lib/Socket/newsletter.d.ts +27 -42
  60. package/lib/Socket/newsletter.d.ts.map +1 -1
  61. package/lib/Socket/newsletter.js +439 -402
  62. package/lib/Socket/newsletter.js.map +1 -1
  63. package/lib/Socket/socket.d.ts +2 -6
  64. package/lib/Socket/socket.d.ts.map +1 -1
  65. package/lib/Socket/socket.js +26 -62
  66. package/lib/Socket/socket.js.map +1 -1
  67. package/lib/Types/Auth.d.ts +0 -1
  68. package/lib/Types/Auth.d.ts.map +1 -1
  69. package/lib/Types/Bussines.d.ts +34 -22
  70. package/lib/Types/Call.d.ts +1 -1
  71. package/lib/Types/Call.d.ts.map +1 -1
  72. package/lib/Types/Chat.d.ts +0 -1
  73. package/lib/Types/Chat.d.ts.map +1 -1
  74. package/lib/Types/Contact.d.ts +0 -2
  75. package/lib/Types/Contact.d.ts.map +1 -1
  76. package/lib/Types/Events.d.ts +1 -20
  77. package/lib/Types/Events.d.ts.map +1 -1
  78. package/lib/Types/GroupMetadata.d.ts +1 -4
  79. package/lib/Types/GroupMetadata.d.ts.map +1 -1
  80. package/lib/Types/Message.d.ts +348 -354
  81. package/lib/Types/Message.d.ts.map +1 -1
  82. package/lib/Types/Message.js +0 -4
  83. package/lib/Types/Message.js.map +1 -1
  84. package/lib/Types/{Mex.d.ts → Newsletter.d.ts} +7 -26
  85. package/lib/Types/Newsletter.d.ts.map +1 -0
  86. package/lib/Types/{Mex.js → Newsletter.js} +3 -11
  87. package/lib/Types/Newsletter.js.map +1 -0
  88. package/lib/Types/Signal.d.ts +1 -12
  89. package/lib/Types/Signal.d.ts.map +1 -1
  90. package/lib/Types/Socket.d.ts +148 -135
  91. package/lib/Types/Socket.d.ts.map +1 -1
  92. package/lib/Types/Socket.js.map +1 -1
  93. package/lib/Types/State.d.ts +0 -65
  94. package/lib/Types/State.d.ts.map +1 -1
  95. package/lib/Types/State.js +0 -43
  96. package/lib/Types/State.js.map +1 -1
  97. package/lib/Types/index.d.ts +52 -52
  98. package/lib/Types/index.d.ts.map +1 -1
  99. package/lib/Types/index.js +30 -23
  100. package/lib/Types/index.js.map +1 -1
  101. package/lib/Utils/auth-utils.d.ts +0 -5
  102. package/lib/Utils/auth-utils.d.ts.map +1 -1
  103. package/lib/Utils/auth-utils.js +0 -12
  104. package/lib/Utils/auth-utils.js.map +1 -1
  105. package/lib/Utils/browser-utils.d.ts.map +1 -1
  106. package/lib/Utils/browser-utils.js +0 -1
  107. package/lib/Utils/browser-utils.js.map +1 -1
  108. package/lib/Utils/chat-utils.d.ts +4 -34
  109. package/lib/Utils/chat-utils.d.ts.map +1 -1
  110. package/lib/Utils/chat-utils.js +20 -80
  111. package/lib/Utils/chat-utils.js.map +1 -1
  112. package/lib/Utils/crypto.d.ts +12 -12
  113. package/lib/Utils/crypto.d.ts.map +1 -1
  114. package/lib/Utils/crypto.js.map +1 -1
  115. package/lib/Utils/decode-wa-message.d.ts +0 -18
  116. package/lib/Utils/decode-wa-message.d.ts.map +1 -1
  117. package/lib/Utils/decode-wa-message.js +0 -34
  118. package/lib/Utils/decode-wa-message.js.map +1 -1
  119. package/lib/Utils/event-buffer.d.ts +0 -2
  120. package/lib/Utils/event-buffer.d.ts.map +1 -1
  121. package/lib/Utils/event-buffer.js +1 -49
  122. package/lib/Utils/event-buffer.js.map +1 -1
  123. package/lib/Utils/generics.d.ts +2 -3
  124. package/lib/Utils/generics.d.ts.map +1 -1
  125. package/lib/Utils/generics.js +1 -10
  126. package/lib/Utils/generics.js.map +1 -1
  127. package/lib/Utils/history.d.ts +0 -2
  128. package/lib/Utils/history.d.ts.map +1 -1
  129. package/lib/Utils/history.js +9 -12
  130. package/lib/Utils/history.js.map +1 -1
  131. package/lib/Utils/identity-change-handler.d.ts +0 -7
  132. package/lib/Utils/identity-change-handler.d.ts.map +1 -1
  133. package/lib/Utils/identity-change-handler.js +0 -1
  134. package/lib/Utils/identity-change-handler.js.map +1 -1
  135. package/lib/Utils/index.d.ts +23 -30
  136. package/lib/Utils/index.d.ts.map +1 -1
  137. package/lib/Utils/index.js +2 -9
  138. package/lib/Utils/index.js.map +1 -1
  139. package/lib/Utils/link-preview.js +2 -2
  140. package/lib/Utils/link-preview.js.map +1 -1
  141. package/lib/Utils/message-retry-manager.d.ts +0 -5
  142. package/lib/Utils/message-retry-manager.d.ts.map +1 -1
  143. package/lib/Utils/message-retry-manager.js +0 -40
  144. package/lib/Utils/message-retry-manager.js.map +1 -1
  145. package/lib/Utils/messages-media.d.ts +13 -45
  146. package/lib/Utils/messages-media.d.ts.map +1 -1
  147. package/lib/Utils/messages-media.js +98 -293
  148. package/lib/Utils/messages-media.js.map +1 -1
  149. package/lib/Utils/messages.d.ts +3 -16
  150. package/lib/Utils/messages.d.ts.map +1 -1
  151. package/lib/Utils/messages.js +1123 -1219
  152. package/lib/Utils/messages.js.map +1 -1
  153. package/lib/Utils/noise-handler.d.ts +1 -1
  154. package/lib/Utils/process-message.d.ts.map +1 -1
  155. package/lib/Utils/process-message.js +1 -103
  156. package/lib/Utils/process-message.js.map +1 -1
  157. package/lib/Utils/rich-messages.d.ts +277 -0
  158. package/lib/Utils/rich-messages.d.ts.map +1 -0
  159. package/lib/Utils/rich-messages.js +1144 -0
  160. package/lib/Utils/rich-messages.js.map +1 -0
  161. package/lib/Utils/signal.d.ts +0 -13
  162. package/lib/Utils/signal.d.ts.map +1 -1
  163. package/lib/Utils/signal.js +0 -42
  164. package/lib/Utils/signal.js.map +1 -1
  165. package/lib/Utils/sticker-pack.d.ts +10 -0
  166. package/lib/Utils/sticker-pack.js +111 -0
  167. package/lib/Utils/sync-action-utils.d.ts.map +1 -1
  168. package/lib/Utils/sync-action-utils.js +0 -1
  169. package/lib/Utils/sync-action-utils.js.map +1 -1
  170. package/lib/Utils/tc-token-utils.d.ts +1 -26
  171. package/lib/Utils/tc-token-utils.d.ts.map +1 -1
  172. package/lib/Utils/tc-token-utils.js +5 -151
  173. package/lib/Utils/tc-token-utils.js.map +1 -1
  174. package/lib/Utils/validate-connection.d.ts +0 -1
  175. package/lib/Utils/validate-connection.d.ts.map +1 -1
  176. package/lib/Utils/validate-connection.js +3 -13
  177. package/lib/Utils/validate-connection.js.map +1 -1
  178. package/lib/WABinary/decode.d.ts +1 -1
  179. package/lib/WABinary/decode.d.ts.map +1 -1
  180. package/lib/WABinary/generic-utils.d.ts +3 -1
  181. package/lib/WABinary/generic-utils.d.ts.map +1 -1
  182. package/lib/WABinary/generic-utils.js +78 -0
  183. package/lib/WABinary/generic-utils.js.map +1 -1
  184. package/lib/WABinary/jid-utils.d.ts +0 -11
  185. package/lib/WABinary/jid-utils.d.ts.map +1 -1
  186. package/lib/WABinary/jid-utils.js +0 -33
  187. package/lib/WABinary/jid-utils.js.map +1 -1
  188. package/lib/WAM/encode.d.ts +1 -1
  189. package/lib/WAM/encode.d.ts.map +1 -1
  190. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -1
  191. package/lib/WAUSync/Protocols/USyncContactProtocol.js +3 -26
  192. package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -1
  193. package/lib/WAUSync/Protocols/index.d.ts +0 -1
  194. package/lib/WAUSync/Protocols/index.d.ts.map +1 -1
  195. package/lib/WAUSync/Protocols/index.js +0 -1
  196. package/lib/WAUSync/Protocols/index.js.map +1 -1
  197. package/lib/WAUSync/USyncQuery.d.ts +0 -1
  198. package/lib/WAUSync/USyncQuery.d.ts.map +1 -1
  199. package/lib/WAUSync/USyncQuery.js +2 -6
  200. package/lib/WAUSync/USyncQuery.js.map +1 -1
  201. package/lib/WAUSync/USyncUser.d.ts +0 -4
  202. package/lib/WAUSync/USyncUser.d.ts.map +1 -1
  203. package/lib/WAUSync/USyncUser.js +0 -8
  204. package/lib/WAUSync/USyncUser.js.map +1 -1
  205. package/lib/index.d.ts +1 -1
  206. package/lib/index.d.ts.map +1 -1
  207. package/lib/index.js +1 -4
  208. package/lib/index.js.map +1 -1
  209. package/package.json +30 -34
  210. package/LICENSE +0 -21
  211. package/engine-requirements.js +0 -10
  212. package/lib/Socket/smgss.d.ts +0 -119
  213. package/lib/Socket/smgss.d.ts.map +0 -1
  214. package/lib/Socket/smgss.js +0 -453
  215. package/lib/Socket/smgss.js.map +0 -1
  216. package/lib/Store/index.d.ts +0 -4
  217. package/lib/Store/index.d.ts.map +0 -1
  218. package/lib/Store/index.js +0 -4
  219. package/lib/Store/index.js.map +0 -1
  220. package/lib/Store/make-in-memory-store.d.ts +0 -132
  221. package/lib/Store/make-in-memory-store.d.ts.map +0 -1
  222. package/lib/Store/make-in-memory-store.js +0 -450
  223. package/lib/Store/make-in-memory-store.js.map +0 -1
  224. package/lib/Store/make-ordered-dictionary.d.ts +0 -14
  225. package/lib/Store/make-ordered-dictionary.d.ts.map +0 -1
  226. package/lib/Store/make-ordered-dictionary.js +0 -80
  227. package/lib/Store/make-ordered-dictionary.js.map +0 -1
  228. package/lib/Store/object-repository.d.ts +0 -13
  229. package/lib/Store/object-repository.d.ts.map +0 -1
  230. package/lib/Store/object-repository.js +0 -24
  231. package/lib/Store/object-repository.js.map +0 -1
  232. package/lib/Types/Mex.d.ts.map +0 -1
  233. package/lib/Types/Mex.js.map +0 -1
  234. package/lib/Utils/button-handler.d.ts +0 -28
  235. package/lib/Utils/button-handler.d.ts.map +0 -1
  236. package/lib/Utils/button-handler.js +0 -140
  237. package/lib/Utils/button-handler.js.map +0 -1
  238. package/lib/Utils/companion-reg-client-utils.d.ts +0 -17
  239. package/lib/Utils/companion-reg-client-utils.d.ts.map +0 -1
  240. package/lib/Utils/companion-reg-client-utils.js +0 -35
  241. package/lib/Utils/companion-reg-client-utils.js.map +0 -1
  242. package/lib/Utils/interactive.d.ts +0 -60
  243. package/lib/Utils/interactive.d.ts.map +0 -1
  244. package/lib/Utils/interactive.js +0 -224
  245. package/lib/Utils/interactive.js.map +0 -1
  246. package/lib/Utils/message-composer.d.ts +0 -93
  247. package/lib/Utils/message-composer.d.ts.map +0 -1
  248. package/lib/Utils/message-composer.js +0 -311
  249. package/lib/Utils/message-composer.js.map +0 -1
  250. package/lib/Utils/messages-newsletter.d.ts +0 -74
  251. package/lib/Utils/messages-newsletter.d.ts.map +0 -1
  252. package/lib/Utils/messages-newsletter.js +0 -128
  253. package/lib/Utils/messages-newsletter.js.map +0 -1
  254. package/lib/Utils/shortcake-crypto.d.ts +0 -36
  255. package/lib/Utils/shortcake-crypto.d.ts.map +0 -1
  256. package/lib/Utils/shortcake-crypto.js +0 -71
  257. package/lib/Utils/shortcake-crypto.js.map +0 -1
  258. package/lib/Utils/shortcake.d.ts +0 -36
  259. package/lib/Utils/shortcake.d.ts.map +0 -1
  260. package/lib/Utils/shortcake.js +0 -162
  261. package/lib/Utils/shortcake.js.map +0 -1
  262. package/lib/Utils/use-single-file-auth-state.d.ts +0 -6
  263. package/lib/Utils/use-single-file-auth-state.d.ts.map +0 -1
  264. package/lib/Utils/use-single-file-auth-state.js +0 -111
  265. package/lib/Utils/use-single-file-auth-state.js.map +0 -1
  266. package/lib/Utils/use-sqlite-auth-state.d.ts +0 -14
  267. package/lib/Utils/use-sqlite-auth-state.d.ts.map +0 -1
  268. package/lib/Utils/use-sqlite-auth-state.js +0 -107
  269. package/lib/Utils/use-sqlite-auth-state.js.map +0 -1
  270. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +0 -10
  271. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +0 -1
  272. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +0 -25
  273. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +0 -1
@@ -1,39 +1,22 @@
1
1
  import NodeCache from '@cacheable/node-cache';
2
2
  import { Boom } from '@hapi/boom';
3
3
  import { proto } from '../../WAProto/index.js';
4
- import { DEFAULT_CACHE_TTLS, HISTORY_SYNC_PAUSED_TIMEOUT_MS, PROCESSABLE_HISTORY_TYPES } from '../Defaults/index.js';
5
- import { ALL_WA_PATCH_NAMES, WAMessageStubType } from '../Types/index.js';
4
+ import { DEFAULT_CACHE_TTLS, PROCESSABLE_HISTORY_TYPES } from '../Defaults/index.js';
5
+ import { ALL_WA_PATCH_NAMES } from '../Types/index.js';
6
6
  import { SyncState } from '../Types/State.js';
7
- import { chatModificationToAppPatch, decodePatches, decodeSyncdSnapshot, encodeSyncdPatch, ensureLTHashStateVersion, extractSyncdPatches, generateProfilePicture, getHistoryMsg, isAppStateSyncIrrecoverable, isMissingKeyError, MAX_SYNC_ATTEMPTS, newLTHashState, processSyncAction } from '../Utils/index.js';
7
+ import { chatModificationToAppPatch, decodePatches, decodeSyncdSnapshot, encodeSyncdPatch, extractSyncdPatches, generateProfilePicture, getHistoryMsg, newLTHashState, processSyncAction } from '../Utils/index.js';
8
8
  import { makeMutex } from '../Utils/make-mutex.js';
9
9
  import processMessage from '../Utils/process-message.js';
10
10
  import { buildTcTokenFromJid } from '../Utils/tc-token-utils.js';
11
- import { getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isLidUser, isPnUser, jidDecode, jidNormalizedUser, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary/index.js';
11
+ import { getBinaryNodeChild, getBinaryNodeChildren, jidDecode, jidNormalizedUser, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary/index.js';
12
12
  import { USyncQuery, USyncUser } from '../WAUSync/index.js';
13
13
  import { makeSocket } from './socket.js';
14
- export const buildProfilePictureQueryContent = (type, tcTokenContent) => {
15
- const picture = { tag: 'picture', attrs: { type, query: 'url' } };
16
- if (tcTokenContent?.length) {
17
- picture.content = tcTokenContent;
18
- }
19
- return [picture];
20
- };
21
- const USER_ID_CACHE = new Map();
14
+ const MAX_SYNC_ATTEMPTS = 2;
22
15
  export const makeChatsSocket = (config) => {
23
16
  const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, getMessage } = config;
24
17
  const sock = makeSocket(config);
25
- const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, sendUnifiedSession, registerSocketEndHandler } = sock;
26
- const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping);
18
+ const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, sendUnifiedSession } = sock;
27
19
  let privacySettings;
28
- /** Server-assigned AB props for protocol behavior. */
29
- const serverProps = {
30
- /** AB prop 10518: gate tctoken on 1:1 messages. Default true (safe: avoids 463). */
31
- privacyTokenOn1to1: true,
32
- /** AB prop 9666: gate tctoken on profile picture IQs. WA Web default: true. */
33
- profilePicPrivacyToken: true,
34
- /** AB prop 14303: issue tctokens to LID instead of PN. WA Web default: false. */
35
- lidTrustedTokenIssueToLid: false
36
- };
37
20
  let syncState = SyncState.Connecting;
38
21
  /** this mutex ensures that messages are processed in order */
39
22
  const messageMutex = makeMutex();
@@ -45,20 +28,14 @@ export const makeChatsSocket = (config) => {
45
28
  const notificationMutex = makeMutex();
46
29
  // Timeout for AwaitingInitialSync state
47
30
  let awaitingSyncTimeout;
48
- // In-memory history sync completion tracking (resets on reconnection)
49
- const historySyncStatus = {
50
- initialBootstrapComplete: false,
51
- recentSyncComplete: false
52
- };
53
- let historySyncPausedTimeout;
54
- // Collections blocked on missing app state sync keys (mirrors WA Web's "Blocked" state).
55
- // When a key arrives via APP_STATE_SYNC_KEY_SHARE, these are re-synced.
56
- const blockedCollections = new Set();
57
31
  const placeholderResendCache = config.placeholderResendCache ||
58
32
  new NodeCache({
59
33
  stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
60
34
  useClones: false
61
35
  });
36
+ if (!config.placeholderResendCache) {
37
+ config.placeholderResendCache = placeholderResendCache;
38
+ }
62
39
  /** helper function to fetch the given app state sync key */
63
40
  const getAppStateSyncKey = async (keyId) => {
64
41
  const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId]);
@@ -195,41 +172,8 @@ export const makeChatsSocket = (config) => {
195
172
  return result.list;
196
173
  }
197
174
  };
198
- const findUserId = async (pnOrLid) => {
199
- const cached = USER_ID_CACHE.get(pnOrLid);
200
- if (cached) {
201
- return cached;
202
- }
203
- const userId = { phoneNumber: '', lid: '' };
204
- if (isPnUser(pnOrLid) || isHostedPnUser(pnOrLid)) {
205
- userId.phoneNumber = pnOrLid;
206
- const lid = await signalRepository.lidMapping.getLIDForPN(pnOrLid);
207
- if (!lid) {
208
- userId.lid = 'id-not-found';
209
- return userId;
210
- }
211
- userId.lid = lid;
212
- }
213
- else if (isLidUser(pnOrLid) || isHostedLidUser(pnOrLid)) {
214
- userId.lid = pnOrLid;
215
- const pn = await signalRepository.lidMapping.getPNForLID(pnOrLid);
216
- if (!pn) {
217
- userId.phoneNumber = 'id-not-found';
218
- return userId;
219
- }
220
- userId.phoneNumber = pn;
221
- }
222
- else {
223
- throw new Boom('Invalid id input to find user ids', { statusCode: 400 });
224
- }
225
- userId.phoneNumber = jidNormalizedUser(userId.phoneNumber);
226
- userId.lid = jidNormalizedUser(userId.lid);
227
- USER_ID_CACHE.set(userId.phoneNumber, userId);
228
- USER_ID_CACHE.set(userId.lid, userId);
229
- return userId;
230
- };
231
175
  /** update the profile picture for yourself or a group */
232
- const updateProfilePicture = async (jid, content, dimensions, options) => {
176
+ const updateProfilePicture = async (jid, content, dimensions) => {
233
177
  let targetJid;
234
178
  if (!jid) {
235
179
  throw new Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
@@ -240,7 +184,7 @@ export const makeChatsSocket = (config) => {
240
184
  else {
241
185
  targetJid = undefined;
242
186
  }
243
- const { img } = await generateProfilePicture(content, dimensions, options);
187
+ const { img } = await generateProfilePicture(content, dimensions);
244
188
  await query({
245
189
  tag: 'iq',
246
190
  attrs: {
@@ -314,42 +258,6 @@ export const makeChatsSocket = (config) => {
314
258
  return getBinaryNodeChildren(listNode, 'item').map(n => n.attrs.jid);
315
259
  };
316
260
  const updateBlockStatus = async (jid, action) => {
317
- const normalizedJid = jidNormalizedUser(jid);
318
- let lid;
319
- let pn_jid;
320
- if (isLidUser(normalizedJid) || isHostedLidUser(normalizedJid)) {
321
- lid = normalizedJid;
322
- if (action === 'block') {
323
- const pn = await signalRepository.lidMapping.getPNForLID(normalizedJid);
324
- if (!pn) {
325
- throw new Boom(`Unable to resolve PN JID for LID: ${jid}`, { statusCode: 400 });
326
- }
327
- pn_jid = jidNormalizedUser(pn);
328
- }
329
- }
330
- else if (isPnUser(normalizedJid) || isHostedPnUser(normalizedJid)) {
331
- const mapped = await signalRepository.lidMapping.getLIDForPN(normalizedJid);
332
- if (!mapped) {
333
- throw new Boom(`Unable to resolve LID for PN JID: ${jid}`, { statusCode: 400 });
334
- }
335
- lid = mapped;
336
- if (action === 'block') {
337
- pn_jid = jidNormalizedUser(normalizedJid);
338
- }
339
- }
340
- else {
341
- throw new Boom(`Invalid jid: ${jid}`, { statusCode: 400 });
342
- }
343
- const itemAttrs = {
344
- action,
345
- jid: lid
346
- };
347
- if (action === 'block') {
348
- if (!pn_jid) {
349
- throw new Boom(`pn_jid required for block: ${jid}`, { statusCode: 400 });
350
- }
351
- itemAttrs.pn_jid = pn_jid;
352
- }
353
261
  await query({
354
262
  tag: 'iq',
355
263
  attrs: {
@@ -360,7 +268,10 @@ export const makeChatsSocket = (config) => {
360
268
  content: [
361
269
  {
362
270
  tag: 'item',
363
- attrs: itemAttrs
271
+ attrs: {
272
+ action,
273
+ jid
274
+ }
364
275
  }
365
276
  ]
366
277
  });
@@ -459,9 +370,6 @@ export const makeChatsSocket = (config) => {
459
370
  const collectionsToHandle = new Set(collections);
460
371
  // in case something goes wrong -- ensure we don't enter a loop that cannot be exited from
461
372
  const attemptsMap = {};
462
- // collections that failed and need a full snapshot on retry
463
- // mirrors WA Web's ErrorFatal -> force snapshot behavior
464
- const forceSnapshotCollections = new Set();
465
373
  // keep executing till all collections are done
466
374
  // sometimes a single patch request will not return all the patches (God knows why)
467
375
  // so we fetch till they're all done (this is determined by the "has_more_patches" flag)
@@ -472,7 +380,6 @@ export const makeChatsSocket = (config) => {
472
380
  const result = await authState.keys.get('app-state-sync-version', [name]);
473
381
  let state = result[name];
474
382
  if (state) {
475
- state = ensureLTHashStateVersion(state);
476
383
  if (typeof initialVersionMap[name] === 'undefined') {
477
384
  initialVersionMap[name] = state.version;
478
385
  }
@@ -481,18 +388,14 @@ export const makeChatsSocket = (config) => {
481
388
  state = newLTHashState();
482
389
  }
483
390
  states[name] = state;
484
- const shouldForceSnapshot = forceSnapshotCollections.has(name);
485
- if (shouldForceSnapshot) {
486
- forceSnapshotCollections.delete(name);
487
- }
488
- logger.info(`resyncing ${name} from v${state.version}${shouldForceSnapshot ? ' (forcing snapshot)' : ''}`);
391
+ logger.info(`resyncing ${name} from v${state.version}`);
489
392
  nodes.push({
490
393
  tag: 'collection',
491
394
  attrs: {
492
395
  name,
493
396
  version: state.version.toString(),
494
- // return snapshot if syncing from scratch or forcing after a failed attempt
495
- return_snapshot: (shouldForceSnapshot || !state.version).toString()
397
+ // return snapshot if being synced from scratch
398
+ return_snapshot: (!state.version).toString()
496
399
  }
497
400
  });
498
401
  }
@@ -518,7 +421,7 @@ export const makeChatsSocket = (config) => {
518
421
  const { patches, hasMorePatches, snapshot } = decoded[name];
519
422
  try {
520
423
  if (snapshot) {
521
- const { state: newState, mutationMap } = await decodeSyncdSnapshot(name, snapshot, getCachedAppStateSyncKey, initialVersionMap[name], appStateMacVerification.snapshot, logger);
424
+ const { state: newState, mutationMap } = await decodeSyncdSnapshot(name, snapshot, getCachedAppStateSyncKey, initialVersionMap[name], appStateMacVerification.snapshot);
522
425
  states[name] = newState;
523
426
  Object.assign(globalMutationMap, mutationMap);
524
427
  logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`);
@@ -541,37 +444,19 @@ export const makeChatsSocket = (config) => {
541
444
  }
542
445
  }
543
446
  catch (error) {
447
+ // if retry attempts overshoot
448
+ // or key not found
449
+ const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS ||
450
+ error.output?.statusCode === 404 ||
451
+ error.name === 'TypeError';
452
+ logger.info({ name, error: error.stack }, `failed to sync state from version${isIrrecoverableError ? '' : ', removing and trying from scratch'}`);
453
+ await authState.keys.set({ 'app-state-sync-version': { [name]: null } });
454
+ // increment number of retries
544
455
  attemptsMap[name] = (attemptsMap[name] || 0) + 1;
545
- const logData = {
546
- name,
547
- attempt: attemptsMap[name],
548
- version: states[name].version,
549
- statusCode: error.output?.statusCode,
550
- errorType: error.name,
551
- error: error.stack
552
- };
553
- if (isMissingKeyError(error) && attemptsMap[name] >= MAX_SYNC_ATTEMPTS) {
554
- // WA Web treats missing keys as "Blocked" — park the collection
555
- // until the key arrives via APP_STATE_SYNC_KEY_SHARE.
556
- logger.warn(logData, `${name} blocked on missing key from v${states[name].version}, parking after ${attemptsMap[name]} attempts`);
557
- blockedCollections.add(name);
558
- collectionsToHandle.delete(name);
559
- }
560
- else if (isMissingKeyError(error)) {
561
- // Retry with a snapshot which may use a different key.
562
- logger.info(logData, `${name} blocked on missing key from v${states[name].version}, retrying with snapshot`);
563
- forceSnapshotCollections.add(name);
564
- }
565
- else if (isAppStateSyncIrrecoverable(error, attemptsMap[name])) {
566
- logger.warn(logData, `failed to sync ${name} from v${states[name].version}, giving up`);
456
+ if (isIrrecoverableError) {
457
+ // stop retrying
567
458
  collectionsToHandle.delete(name);
568
459
  }
569
- else {
570
- logger.info(logData, `failed to sync ${name} from v${states[name].version}, forcing snapshot retry`);
571
- // force a full snapshot on retry to recover from
572
- // corrupted local state (e.g. LTHash MAC mismatch)
573
- forceSnapshotCollections.add(name);
574
- }
575
460
  }
576
461
  }
577
462
  }
@@ -587,21 +472,8 @@ export const makeChatsSocket = (config) => {
587
472
  * type = "image for the high res picture"
588
473
  */
589
474
  const profilePictureUrl = async (jid, type = 'preview', timeoutMs) => {
590
- // WA Web only includes tctoken for user JIDs (not groups/newsletters)
591
- // and never for own profile pic (Chat model for self has no tcToken).
592
- // Including tctoken for own JID causes the server to never respond.
593
- const normalizedJid = jidNormalizedUser(jid);
594
- const isUserJid = isPnUser(normalizedJid) || isLidUser(normalizedJid);
595
- const me = authState.creds.me;
596
- const isSelf = me && (normalizedJid === jidNormalizedUser(me.id) || (me.lid && normalizedJid === jidNormalizedUser(me.lid)));
597
- let tcTokenContent;
598
- if (serverProps.profilePicPrivacyToken && isUserJid && !isSelf) {
599
- tcTokenContent = await buildTcTokenFromJid({
600
- authState,
601
- jid: normalizedJid,
602
- getLIDForPN
603
- });
604
- }
475
+ const baseContent = [{ tag: 'picture', attrs: { type, query: 'url' } }];
476
+ const tcTokenContent = await buildTcTokenFromJid({ authState, jid, baseContent });
605
477
  jid = jidNormalizedUser(jid);
606
478
  const result = await query({
607
479
  tag: 'iq',
@@ -611,7 +483,7 @@ export const makeChatsSocket = (config) => {
611
483
  type: 'get',
612
484
  xmlns: 'w:profile:picture'
613
485
  },
614
- content: buildProfilePictureQueryContent(type, tcTokenContent)
486
+ content: tcTokenContent
615
487
  }, timeoutMs);
616
488
  const child = getBinaryNodeChild(result, 'picture');
617
489
  return child?.attrs?.url;
@@ -677,12 +549,7 @@ export const makeChatsSocket = (config) => {
677
549
  * @param tcToken token for subscription, use if present
678
550
  */
679
551
  const presenceSubscribe = async (toJid) => {
680
- // Only include tctoken for user JIDs groups/newsletters don't use tctokens
681
- const normalizedToJid = jidNormalizedUser(toJid);
682
- const isUserJid = isPnUser(normalizedToJid) || isLidUser(normalizedToJid);
683
- const tcTokenContent = isUserJid
684
- ? await buildTcTokenFromJid({ authState, jid: normalizedToJid, getLIDForPN })
685
- : undefined;
552
+ const tcTokenContent = await buildTcTokenFromJid({ authState, jid: toJid });
686
553
  return sendNode({
687
554
  tag: 'presence',
688
555
  attrs: {
@@ -703,8 +570,7 @@ export const makeChatsSocket = (config) => {
703
570
  if (tag === 'presence') {
704
571
  presence = {
705
572
  lastKnownPresence: attrs.type === 'unavailable' ? 'unavailable' : 'available',
706
- lastSeen: attrs.last && attrs.last !== 'deny' ? +attrs.last : undefined,
707
- groupOnlineCount: attrs.count ? +attrs.count : undefined
573
+ lastSeen: attrs.last && attrs.last !== 'deny' ? +attrs.last : undefined
708
574
  };
709
575
  }
710
576
  else if (Array.isArray(content)) {
@@ -738,7 +604,7 @@ export const makeChatsSocket = (config) => {
738
604
  logger.debug({ patch: patchCreate }, 'applying app patch');
739
605
  await resyncAppState([name], false);
740
606
  const { [name]: currentSyncVersion } = await authState.keys.get('app-state-sync-version', [name]);
741
- initial = currentSyncVersion ? ensureLTHashStateVersion(currentSyncVersion) : newLTHashState();
607
+ initial = currentSyncVersion || newLTHashState();
742
608
  encodeResult = await encodeSyncdPatch(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey);
743
609
  const { patch, state } = encodeResult;
744
610
  const node = {
@@ -784,21 +650,22 @@ export const makeChatsSocket = (config) => {
784
650
  }
785
651
  }
786
652
  };
787
- /** fetch AB props */
653
+ /** sending non-abt props may fix QR scan fail if server expects */
788
654
  const fetchProps = async () => {
655
+ //TODO: implement both protocol 1 and protocol 2 prop fetching, specially for abKey for WM
789
656
  const resultNode = await query({
790
657
  tag: 'iq',
791
658
  attrs: {
792
659
  to: S_WHATSAPP_NET,
793
- xmlns: 'abt',
660
+ xmlns: 'w',
794
661
  type: 'get'
795
662
  },
796
663
  content: [
797
664
  {
798
665
  tag: 'props',
799
666
  attrs: {
800
- protocol: '1',
801
- ...(authState?.creds?.lastPropHash ? { hash: authState.creds.lastPropHash } : {})
667
+ protocol: '2',
668
+ hash: authState?.creds?.lastPropHash || ''
802
669
  }
803
670
  }
804
671
  ]
@@ -813,20 +680,7 @@ export const makeChatsSocket = (config) => {
813
680
  }
814
681
  props = reduceBinaryNodeToDictionary(propsNode, 'prop');
815
682
  }
816
- // Extract protocol-relevant AB props (only the ones we need)
817
- const privacyTokenProp = props['10518'] ?? props['privacy_token_sending_on_all_1_on_1_messages'];
818
- if (privacyTokenProp !== undefined) {
819
- serverProps.privacyTokenOn1to1 = privacyTokenProp === 'true' || privacyTokenProp === '1';
820
- }
821
- const profilePicProp = props['9666'] ?? props['profile_scraping_privacy_token_in_photo_iq'];
822
- if (profilePicProp !== undefined) {
823
- serverProps.profilePicPrivacyToken = profilePicProp === 'true' || profilePicProp === '1';
824
- }
825
- const lidIssueProp = props['14303'] ?? props['lid_trusted_token_issue_to_lid'];
826
- if (lidIssueProp !== undefined) {
827
- serverProps.lidTrustedTokenIssueToLid = lidIssueProp === 'true' || lidIssueProp === '1';
828
- }
829
- logger.debug({ serverProps }, 'fetched props');
683
+ logger.debug('fetched props');
830
684
  return props;
831
685
  };
832
686
  /**
@@ -948,36 +802,7 @@ export const makeChatsSocket = (config) => {
948
802
  const executeInitQueries = async () => {
949
803
  await Promise.all([fetchProps(), fetchBlocklist(), fetchPrivacySettings()]);
950
804
  };
951
- const isWASystemNotification = (msg) => {
952
- const content = msg?.message;
953
- if (!content)
954
- return false;
955
- const protoType = content.protocolMessage?.type;
956
- if (protoType === proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION ||
957
- protoType === proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE ||
958
- protoType === proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE ||
959
- protoType === proto.Message.ProtocolMessage.Type.LID_MIGRATION_MAPPING_SYNC) {
960
- return true;
961
- }
962
- if (msg.messageStubType && !content.conversation && !content.extendedTextMessage) {
963
- const stub = msg.messageStubType;
964
- const SYSTEM_STUB_TYPES = new Set([
965
- WAMessageStubType.E2E_DEVICE_CHANGED,
966
- WAMessageStubType.E2E_ENCRYPTED,
967
- WAMessageStubType.E2E_IDENTITY_CHANGED,
968
- WAMessageStubType.CIPHERTEXT,
969
- WAMessageStubType.BIZ_PRIVACY_MODE_TO_BSP,
970
- WAMessageStubType.BIZ_PRIVACY_MODE_TO_FB
971
- ]);
972
- if (SYSTEM_STUB_TYPES.has(stub))
973
- return true;
974
- }
975
- return false;
976
- };
977
805
  const upsertMessage = ev.createBufferedFunction(async (msg, type) => {
978
- if (isWASystemNotification(msg)) {
979
- msg.isSystemNotification = true;
980
- }
981
806
  ev.emit('messages.upsert', { messages: [msg], type });
982
807
  if (!!msg.pushName) {
983
808
  let jid = msg.key.fromMe ? authState.creds.me.id : msg.key.participant || msg.key.remoteJid;
@@ -995,47 +820,6 @@ export const makeChatsSocket = (config) => {
995
820
  ? shouldSyncHistoryMessage(historyMsg) &&
996
821
  PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType)
997
822
  : false;
998
- if (historyMsg && shouldProcessHistoryMsg) {
999
- const syncType = historyMsg.syncType;
1000
- // INITIAL_BOOTSTRAP — fire immediately, no progress check (same as WA Web K function)
1001
- if (syncType === proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP &&
1002
- !historySyncStatus.initialBootstrapComplete) {
1003
- historySyncStatus.initialBootstrapComplete = true;
1004
- ev.emit('messaging-history.status', {
1005
- syncType,
1006
- status: 'complete',
1007
- explicit: true
1008
- });
1009
- }
1010
- // RECENT with progress === 100 — explicit completion
1011
- if (syncType === proto.HistorySync.HistorySyncType.RECENT &&
1012
- historyMsg.progress === 100 &&
1013
- !historySyncStatus.recentSyncComplete) {
1014
- historySyncStatus.recentSyncComplete = true;
1015
- clearTimeout(historySyncPausedTimeout);
1016
- historySyncPausedTimeout = undefined;
1017
- ev.emit('messaging-history.status', {
1018
- syncType,
1019
- status: 'complete',
1020
- explicit: true
1021
- });
1022
- }
1023
- // Reset 120s paused timeout on any RECENT chunk (like WA Web's handleChunkProgress)
1024
- if (syncType === proto.HistorySync.HistorySyncType.RECENT && !historySyncStatus.recentSyncComplete) {
1025
- clearTimeout(historySyncPausedTimeout);
1026
- historySyncPausedTimeout = setTimeout(() => {
1027
- if (!historySyncStatus.recentSyncComplete) {
1028
- historySyncStatus.recentSyncComplete = true;
1029
- ev.emit('messaging-history.status', {
1030
- syncType: proto.HistorySync.HistorySyncType.RECENT,
1031
- status: 'paused',
1032
- explicit: false
1033
- });
1034
- }
1035
- historySyncPausedTimeout = undefined;
1036
- }, HISTORY_SYNC_PAUSED_TIMEOUT_MS);
1037
- }
1038
- }
1039
823
  // State machine: decide on sync and flush
1040
824
  if (historyMsg && syncState === SyncState.AwaitingInitialSync) {
1041
825
  if (awaitingSyncTimeout) {
@@ -1055,8 +839,6 @@ export const makeChatsSocket = (config) => {
1055
839
  }
1056
840
  const doAppStateSync = async () => {
1057
841
  if (syncState === SyncState.Syncing) {
1058
- // All collections will be synced, so clear any blocked ones
1059
- blockedCollections.clear();
1060
842
  logger.info('Doing app state sync');
1061
843
  await resyncAppState(ALL_WA_PATCH_NAMES, true);
1062
844
  // Sync is complete, go online and flush everything
@@ -1116,11 +898,6 @@ export const makeChatsSocket = (config) => {
1116
898
  }
1117
899
  });
1118
900
  ev.on('connection.update', ({ connection, receivedPendingNotifications }) => {
1119
- if (connection === 'close') {
1120
- blockedCollections.clear();
1121
- clearTimeout(historySyncPausedTimeout);
1122
- historySyncPausedTimeout = undefined;
1123
- }
1124
901
  if (connection === 'open') {
1125
902
  if (fireInitQueries) {
1126
903
  executeInitQueries().catch(error => onUnexpectedError(error, 'init queries'));
@@ -1130,10 +907,6 @@ export const makeChatsSocket = (config) => {
1130
907
  if (!receivedPendingNotifications || syncState !== SyncState.Connecting) {
1131
908
  return;
1132
909
  }
1133
- historySyncStatus.initialBootstrapComplete = false;
1134
- historySyncStatus.recentSyncComplete = false;
1135
- clearTimeout(historySyncPausedTimeout);
1136
- historySyncPausedTimeout = undefined;
1137
910
  syncState = SyncState.AwaitingInitialSync;
1138
911
  logger.info('Connection is now AwaitingInitialSync, buffering events');
1139
912
  ev.buffer();
@@ -1146,49 +919,19 @@ export const makeChatsSocket = (config) => {
1146
919
  setTimeout(() => ev.flush(), 0);
1147
920
  return;
1148
921
  }
1149
- // On reconnection (accountSyncCounter > 0), the server does not push
1150
- // history sync notifications — the device already has its data.
1151
- // Skip the 20s wait and go online immediately.
1152
- if (authState.creds.accountSyncCounter > 0) {
1153
- logger.info('Reconnection with existing sync data, skipping history sync wait. Transitioning to Online.');
1154
- syncState = SyncState.Online;
1155
- setTimeout(() => ev.flush(), 0);
1156
- return;
1157
- }
1158
- logger.info('First connection, awaiting history sync notification with a 20s timeout.');
922
+ logger.info('History sync is enabled, awaiting notification with a 20s timeout.');
1159
923
  if (awaitingSyncTimeout) {
1160
924
  clearTimeout(awaitingSyncTimeout);
1161
925
  }
1162
926
  awaitingSyncTimeout = setTimeout(() => {
1163
927
  if (syncState === SyncState.AwaitingInitialSync) {
928
+ // TODO: investigate
1164
929
  logger.warn('Timeout in AwaitingInitialSync, forcing state to Online and flushing buffer');
1165
930
  syncState = SyncState.Online;
1166
931
  ev.flush();
1167
- // Increment so subsequent reconnections skip the 20s wait.
1168
- // Late-arriving history is still processed via processMessage
1169
- // regardless of the state machine phase.
1170
- const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1;
1171
- ev.emit('creds.update', { accountSyncCounter });
1172
932
  }
1173
933
  }, 20000);
1174
934
  });
1175
- // When an app state sync key arrives (myAppStateKeyId is set) and there are
1176
- // collections blocked on a missing key, trigger a re-sync for just those collections.
1177
- // This mirrors WA Web's Blocked → retry-on-key-arrival behavior.
1178
- ev.on('creds.update', ({ myAppStateKeyId }) => {
1179
- if (!myAppStateKeyId || blockedCollections.size === 0) {
1180
- return;
1181
- }
1182
- // If we're in the middle of a full sync, doAppStateSync handles all collections
1183
- if (syncState === SyncState.Syncing) {
1184
- blockedCollections.clear();
1185
- return;
1186
- }
1187
- const collections = [...blockedCollections];
1188
- blockedCollections.clear();
1189
- logger.info({ collections }, 'app state sync key arrived, re-syncing blocked collections');
1190
- resyncAppState(collections, false).catch(error => onUnexpectedError(error, 'blocked collections resync'));
1191
- });
1192
935
  ev.on('lid-mapping.update', async ({ lid, pn }) => {
1193
936
  try {
1194
937
  await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }]);
@@ -1197,20 +940,8 @@ export const makeChatsSocket = (config) => {
1197
940
  logger.warn({ lid, pn, error }, 'Failed to store LID-PN mapping');
1198
941
  }
1199
942
  });
1200
- registerSocketEndHandler(() => {
1201
- if (awaitingSyncTimeout) {
1202
- clearTimeout(awaitingSyncTimeout);
1203
- awaitingSyncTimeout = undefined;
1204
- }
1205
- if (!config.placeholderResendCache && placeholderResendCache.close) {
1206
- placeholderResendCache.close();
1207
- }
1208
- syncState = SyncState.Connecting;
1209
- privacySettings = undefined;
1210
- });
1211
943
  return {
1212
944
  ...sock,
1213
- serverProps,
1214
945
  createCallLink,
1215
946
  getBotListV2,
1216
947
  messageMutex,
@@ -1226,7 +957,6 @@ export const makeChatsSocket = (config) => {
1226
957
  fetchBlocklist,
1227
958
  fetchStatus,
1228
959
  fetchDisappearingDuration,
1229
- findUserId,
1230
960
  updateProfilePicture,
1231
961
  removeProfilePicture,
1232
962
  updateProfileStatus,
@@ -1248,7 +978,6 @@ export const makeChatsSocket = (config) => {
1248
978
  cleanDirtyBits,
1249
979
  addOrEditContact,
1250
980
  removeContact,
1251
- placeholderResendCache,
1252
981
  addLabel,
1253
982
  addChatLabel,
1254
983
  removeChatLabel,