gifted-baileys 1.5.6 → 1.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. package/README.md +9 -0
  2. package/WAProto/WAProto.proto +969 -88
  3. package/WAProto/index.d.ts +13199 -1260
  4. package/WAProto/index.js +124901 -74525
  5. package/lib/Defaults/baileys-version.json +3 -0
  6. package/lib/Defaults/index.d.ts +284 -0
  7. package/{src → lib}/Defaults/index.js +7 -14
  8. package/lib/Signal/libsignal.d.ts +3 -0
  9. package/lib/Signal/libsignal.js +161 -0
  10. package/lib/Socket/Client/abstract-socket-client.d.ts +15 -0
  11. package/lib/Socket/Client/index.d.ts +2 -0
  12. package/{src → lib}/Socket/Client/index.js +2 -3
  13. package/lib/Socket/Client/mobile-socket-client.d.ts +12 -0
  14. package/lib/Socket/Client/mobile-socket-client.js +65 -0
  15. package/lib/Socket/Client/types.d.ts +17 -0
  16. package/lib/Socket/Client/types.js +13 -0
  17. package/lib/Socket/Client/websocket.d.ts +12 -0
  18. package/lib/Socket/Client/websocket.js +62 -0
  19. package/lib/Socket/business.d.ts +170 -0
  20. package/{src → lib}/Socket/business.js +28 -33
  21. package/lib/Socket/chats.d.ts +81 -0
  22. package/{src → lib}/Socket/chats.js +174 -176
  23. package/lib/Socket/groups.d.ts +115 -0
  24. package/{src → lib}/Socket/groups.js +80 -68
  25. package/lib/Socket/index.d.ts +172 -0
  26. package/{src → lib}/Socket/index.js +4 -1
  27. package/lib/Socket/messages-recv.d.ts +158 -0
  28. package/{src → lib}/Socket/messages-recv.js +378 -211
  29. package/lib/Socket/messages-send.d.ts +155 -0
  30. package/{src → lib}/Socket/messages-send.js +452 -177
  31. package/lib/Socket/newsletter.d.ts +132 -0
  32. package/{src → lib}/Socket/newsletter.js +107 -98
  33. package/lib/Socket/registration.d.ts +264 -0
  34. package/{src → lib}/Socket/registration.js +56 -48
  35. package/lib/Socket/socket.d.ts +44 -0
  36. package/{src → lib}/Socket/socket.js +77 -77
  37. package/lib/Socket/usync.d.ts +37 -0
  38. package/lib/Socket/usync.js +70 -0
  39. package/lib/Store/index.d.ts +3 -0
  40. package/lib/Store/make-cache-manager-store.d.ts +14 -0
  41. package/{src → lib}/Store/make-cache-manager-store.js +25 -34
  42. package/lib/Store/make-in-memory-store.d.ts +118 -0
  43. package/{src → lib}/Store/make-in-memory-store.js +36 -32
  44. package/lib/Store/make-ordered-dictionary.d.ts +13 -0
  45. package/lib/Store/object-repository.d.ts +10 -0
  46. package/{src → lib}/Store/object-repository.js +1 -1
  47. package/lib/Types/Auth.d.ts +109 -0
  48. package/lib/Types/Call.d.ts +13 -0
  49. package/lib/Types/Chat.d.ts +107 -0
  50. package/{src/Types/Contact.ts → lib/Types/Contact.d.ts} +8 -9
  51. package/lib/Types/Events.d.ts +172 -0
  52. package/lib/Types/GroupMetadata.d.ts +56 -0
  53. package/lib/Types/Label.d.ts +46 -0
  54. package/{src/Types/LabelAssociation.ts → lib/Types/LabelAssociation.d.ts} +16 -22
  55. package/lib/Types/Message.d.ts +433 -0
  56. package/lib/Types/Newsletter.d.ts +92 -0
  57. package/lib/Types/Product.d.ts +78 -0
  58. package/lib/Types/Signal.d.ts +57 -0
  59. package/{src/Types/Socket.ts → lib/Types/Socket.d.ts} +61 -68
  60. package/lib/Types/State.d.ts +27 -0
  61. package/lib/Types/USync.d.ts +25 -0
  62. package/lib/Types/index.d.ts +66 -0
  63. package/lib/Utils/auth-utils.d.ts +18 -0
  64. package/{src → lib}/Utils/auth-utils.js +73 -90
  65. package/lib/Utils/baileys-event-stream.d.ts +16 -0
  66. package/lib/Utils/baileys-event-stream.js +63 -0
  67. package/lib/Utils/business.d.ts +22 -0
  68. package/{src → lib}/Utils/business.js +15 -43
  69. package/lib/Utils/chat-utils.d.ts +70 -0
  70. package/{src → lib}/Utils/chat-utils.js +87 -94
  71. package/lib/Utils/crypto.d.ts +40 -0
  72. package/{src → lib}/Utils/crypto.js +4 -2
  73. package/lib/Utils/decode-wa-message.d.ts +36 -0
  74. package/lib/Utils/decode-wa-message.js +226 -0
  75. package/lib/Utils/event-buffer.d.ts +35 -0
  76. package/{src → lib}/Utils/event-buffer.js +4 -13
  77. package/lib/Utils/generics.d.ts +88 -0
  78. package/{src → lib}/Utils/generics.js +67 -86
  79. package/lib/Utils/history.d.ts +19 -0
  80. package/{src → lib}/Utils/history.js +13 -39
  81. package/lib/Utils/index.d.ts +17 -0
  82. package/lib/Utils/link-preview.d.ts +21 -0
  83. package/{src → lib}/Utils/link-preview.js +17 -54
  84. package/lib/Utils/logger.d.ts +2 -0
  85. package/lib/Utils/lt-hash.d.ts +12 -0
  86. package/lib/Utils/make-mutex.d.ts +7 -0
  87. package/{src → lib}/Utils/make-mutex.js +4 -13
  88. package/lib/Utils/messages-media.d.ts +113 -0
  89. package/{src → lib}/Utils/messages-media.js +193 -255
  90. package/lib/Utils/messages.d.ts +77 -0
  91. package/{src → lib}/Utils/messages.js +588 -118
  92. package/lib/Utils/noise-handler.d.ts +20 -0
  93. package/lib/Utils/process-message.d.ts +41 -0
  94. package/{src → lib}/Utils/process-message.js +27 -30
  95. package/lib/Utils/signal.d.ts +33 -0
  96. package/{src → lib}/Utils/signal.js +25 -42
  97. package/lib/Utils/use-multi-file-auth-state.d.ts +12 -0
  98. package/{src → lib}/Utils/use-multi-file-auth-state.js +27 -28
  99. package/lib/Utils/validate-connection.d.ts +11 -0
  100. package/{src → lib}/Utils/validate-connection.js +40 -9
  101. package/lib/WABinary/constants.d.ts +27 -0
  102. package/lib/WABinary/decode.d.ts +6 -0
  103. package/lib/WABinary/encode.d.ts +2 -0
  104. package/{src → lib}/WABinary/encode.js +16 -10
  105. package/lib/WABinary/generic-utils.d.ts +14 -0
  106. package/lib/WABinary/index.d.ts +5 -0
  107. package/lib/WABinary/jid-utils.d.ts +31 -0
  108. package/lib/WABinary/types.d.ts +18 -0
  109. package/lib/WABinary/types.js +2 -0
  110. package/lib/WAM/BinaryInfo.d.ts +8 -0
  111. package/lib/WAM/constants.d.ts +38 -0
  112. package/lib/WAM/encode.d.ts +2 -0
  113. package/lib/WAM/index.d.ts +3 -0
  114. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
  115. package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
  116. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
  117. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
  118. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  119. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
  120. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  121. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  122. package/lib/WAUSync/Protocols/index.d.ts +4 -0
  123. package/lib/WAUSync/Protocols/index.js +20 -0
  124. package/lib/WAUSync/USyncQuery.d.ts +26 -0
  125. package/lib/WAUSync/USyncQuery.js +79 -0
  126. package/lib/WAUSync/USyncUser.d.ts +10 -0
  127. package/lib/WAUSync/USyncUser.js +22 -0
  128. package/lib/WAUSync/index.d.ts +3 -0
  129. package/lib/WAUSync/index.js +19 -0
  130. package/{src → lib}/index.js +1 -0
  131. package/package.json +26 -8
  132. package/LICENSE +0 -21
  133. package/src/Defaults/baileys-version.json +0 -3
  134. package/src/Defaults/index.ts +0 -131
  135. package/src/README.md +0 -1
  136. package/src/Signal/libsignal.js +0 -180
  137. package/src/Signal/libsignal.ts +0 -141
  138. package/src/Socket/Client/abstract-socket-client.ts +0 -19
  139. package/src/Socket/Client/index.ts +0 -3
  140. package/src/Socket/Client/mobile-socket-client.js +0 -78
  141. package/src/Socket/Client/mobile-socket-client.ts +0 -66
  142. package/src/Socket/Client/web-socket-client.js +0 -75
  143. package/src/Socket/Client/web-socket-client.ts +0 -57
  144. package/src/Socket/business.ts +0 -281
  145. package/src/Socket/chats.ts +0 -1030
  146. package/src/Socket/groups.ts +0 -356
  147. package/src/Socket/index.ts +0 -13
  148. package/src/Socket/messages-recv.ts +0 -985
  149. package/src/Socket/messages-send.ts +0 -871
  150. package/src/Socket/newsletter.ts +0 -282
  151. package/src/Socket/registration.ts +0 -250
  152. package/src/Socket/socket.ts +0 -777
  153. package/src/Store/index.ts +0 -3
  154. package/src/Store/make-cache-manager-store.ts +0 -100
  155. package/src/Store/make-in-memory-store.ts +0 -475
  156. package/src/Store/make-ordered-dictionary.ts +0 -86
  157. package/src/Store/object-repository.ts +0 -32
  158. package/src/Tests/test.app-state-sync.js +0 -204
  159. package/src/Tests/test.app-state-sync.ts +0 -207
  160. package/src/Tests/test.event-buffer.js +0 -270
  161. package/src/Tests/test.event-buffer.ts +0 -319
  162. package/src/Tests/test.key-store.js +0 -76
  163. package/src/Tests/test.key-store.ts +0 -92
  164. package/src/Tests/test.libsignal.js +0 -141
  165. package/src/Tests/test.libsignal.ts +0 -186
  166. package/src/Tests/test.media-download.js +0 -93
  167. package/src/Tests/test.media-download.ts +0 -76
  168. package/src/Tests/test.messages.js +0 -33
  169. package/src/Tests/test.messages.ts +0 -37
  170. package/src/Tests/utils.js +0 -34
  171. package/src/Tests/utils.ts +0 -36
  172. package/src/Types/Auth.ts +0 -113
  173. package/src/Types/Call.ts +0 -15
  174. package/src/Types/Chat.ts +0 -106
  175. package/src/Types/Events.ts +0 -93
  176. package/src/Types/GroupMetadata.ts +0 -53
  177. package/src/Types/Label.ts +0 -36
  178. package/src/Types/Message.ts +0 -288
  179. package/src/Types/Newsletter.ts +0 -98
  180. package/src/Types/Product.ts +0 -85
  181. package/src/Types/Signal.ts +0 -68
  182. package/src/Types/State.ts +0 -29
  183. package/src/Types/index.ts +0 -59
  184. package/src/Utils/auth-utils.ts +0 -222
  185. package/src/Utils/baileys-event-stream.js +0 -92
  186. package/src/Utils/baileys-event-stream.ts +0 -66
  187. package/src/Utils/business.ts +0 -275
  188. package/src/Utils/chat-utils.ts +0 -860
  189. package/src/Utils/crypto.ts +0 -131
  190. package/src/Utils/decode-wa-message.js +0 -211
  191. package/src/Utils/decode-wa-message.ts +0 -228
  192. package/src/Utils/event-buffer.ts +0 -613
  193. package/src/Utils/generics.ts +0 -434
  194. package/src/Utils/history.ts +0 -112
  195. package/src/Utils/index.ts +0 -17
  196. package/src/Utils/link-preview.ts +0 -122
  197. package/src/Utils/logger.ts +0 -3
  198. package/src/Utils/lt-hash.ts +0 -61
  199. package/src/Utils/make-mutex.ts +0 -44
  200. package/src/Utils/messages-media.ts +0 -847
  201. package/src/Utils/messages.ts +0 -956
  202. package/src/Utils/noise-handler.ts +0 -197
  203. package/src/Utils/process-message.ts +0 -414
  204. package/src/Utils/signal.ts +0 -177
  205. package/src/Utils/use-multi-file-auth-state.ts +0 -90
  206. package/src/Utils/validate-connection.ts +0 -238
  207. package/src/WABinary/constants.ts +0 -42
  208. package/src/WABinary/decode.ts +0 -265
  209. package/src/WABinary/encode.ts +0 -236
  210. package/src/WABinary/generic-utils.ts +0 -121
  211. package/src/WABinary/index.ts +0 -5
  212. package/src/WABinary/jid-utils.ts +0 -68
  213. package/src/WABinary/types.ts +0 -17
  214. package/src/WAM/BinaryInfo.ts +0 -12
  215. package/src/WAM/constants.ts +0 -15382
  216. package/src/WAM/encode.ts +0 -174
  217. package/src/WAM/index.ts +0 -3
  218. package/src/gifted +0 -1
  219. package/src/index.ts +0 -13
  220. /package/{src → lib}/Defaults/phonenumber-mcc.json +0 -0
  221. /package/{src → lib}/Socket/Client/abstract-socket-client.js +0 -0
  222. /package/{src → lib}/Store/index.js +0 -0
  223. /package/{src → lib}/Store/make-ordered-dictionary.js +0 -0
  224. /package/{src → lib}/Types/Auth.js +0 -0
  225. /package/{src → lib}/Types/Call.js +0 -0
  226. /package/{src → lib}/Types/Chat.js +0 -0
  227. /package/{src → lib}/Types/Contact.js +0 -0
  228. /package/{src → lib}/Types/Events.js +0 -0
  229. /package/{src → lib}/Types/GroupMetadata.js +0 -0
  230. /package/{src → lib}/Types/Label.js +0 -0
  231. /package/{src → lib}/Types/LabelAssociation.js +0 -0
  232. /package/{src → lib}/Types/Message.js +0 -0
  233. /package/{src → lib}/Types/Newsletter.js +0 -0
  234. /package/{src → lib}/Types/Product.js +0 -0
  235. /package/{src → lib}/Types/Signal.js +0 -0
  236. /package/{src → lib}/Types/Socket.js +0 -0
  237. /package/{src → lib}/Types/State.js +0 -0
  238. /package/{src/WABinary/types.js → lib/Types/USync.js} +0 -0
  239. /package/{src → lib}/Types/index.js +0 -0
  240. /package/{src → lib}/Utils/index.js +0 -0
  241. /package/{src → lib}/Utils/logger.js +0 -0
  242. /package/{src → lib}/Utils/lt-hash.js +0 -0
  243. /package/{src → lib}/Utils/noise-handler.js +0 -0
  244. /package/{src → lib}/WABinary/constants.js +0 -0
  245. /package/{src → lib}/WABinary/decode.js +0 -0
  246. /package/{src → lib}/WABinary/generic-utils.js +0 -0
  247. /package/{src → lib}/WABinary/index.js +0 -0
  248. /package/{src → lib}/WABinary/jid-utils.js +0 -0
  249. /package/{src → lib}/WAM/BinaryInfo.js +0 -0
  250. /package/{src → lib}/WAM/constants.js +0 -0
  251. /package/{src → lib}/WAM/encode.js +0 -0
  252. /package/{src → lib}/WAM/index.js +0 -0
@@ -1,871 +0,0 @@
1
-
2
- import { Boom } from '@hapi/boom'
3
- import NodeCache from 'node-cache'
4
- import { proto } from '../../WAProto'
5
- import { DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults'
6
- import { AnyMessageContent, MediaConnInfo, MessageReceiptType, MessageRelayOptions, MiscMessageGenerationOptions, SocketConfig, WAMediaUploadFunctionOpts, WAMessageKey } from '../Types'
7
- import { aggregateMessageKeysNotFromMe, assertMediaContent, bindWaitForEvent, decryptMediaRetryData, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageID, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils'
8
- import { getUrlInfo } from '../Utils/link-preview'
9
- import { areJidsSameUser, BinaryNode, BinaryNodeAttributes, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, isJidNewsLetter, isJidUser, jidDecode, jidEncode, jidNormalizedUser, JidWithDevice, S_WHATSAPP_NET } from '../WABinary'
10
- import { makeNewsletterSocket } from './newsletter'
11
- import ListType = proto.Message.ListMessage.ListType;
12
- import { Readable } from 'stream'
13
-
14
- export const makeMessagesSocket = (config: SocketConfig) => {
15
- const {
16
- logger,
17
- linkPreviewImageThumbnailWidth,
18
- generateHighQualityLinkPreview,
19
- options: axiosOptions,
20
- patchMessageBeforeSending,
21
- } = config
22
- const sock = makeNewsletterSocket(config)
23
- const {
24
- ev,
25
- authState,
26
- processingMutex,
27
- signalRepository,
28
- upsertMessage,
29
- query,
30
- fetchPrivacySettings,
31
- generateMessageTag,
32
- sendNode,
33
- groupMetadata,
34
- groupToggleEphemeral
35
- } = sock
36
-
37
- const userDevicesCache = config.userDevicesCache || new NodeCache({
38
- stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
39
- useClones: false
40
- })
41
-
42
- let mediaConn: Promise<MediaConnInfo>
43
- const refreshMediaConn = async(forceGet = false) => {
44
- const media = await mediaConn
45
- if(!media || forceGet || (new Date().getTime() - media.fetchDate.getTime()) > media.ttl * 1000) {
46
- mediaConn = (async() => {
47
- const result = await query({
48
- tag: 'iq',
49
- attrs: {
50
- type: 'set',
51
- xmlns: 'w:m',
52
- to: S_WHATSAPP_NET,
53
- },
54
- content: [ { tag: 'media_conn', attrs: { } } ]
55
- })
56
- const mediaConnNode = getBinaryNodeChild(result, 'media_conn')
57
- const node: MediaConnInfo = {
58
- hosts: getBinaryNodeChildren(mediaConnNode, 'host').map(
59
- ({ attrs }) => ({
60
- hostname: attrs.hostname,
61
- maxContentLengthBytes: +attrs.maxContentLengthBytes,
62
- })
63
- ),
64
- auth: mediaConnNode!.attrs.auth,
65
- ttl: +mediaConnNode!.attrs.ttl,
66
- fetchDate: new Date()
67
- }
68
- logger.debug('fetched media conn')
69
- return node
70
- })()
71
- }
72
-
73
- return mediaConn
74
- }
75
-
76
- /**
77
- * generic send receipt function
78
- * used for receipts of phone call, read, delivery etc.
79
- * */
80
- const sendReceipt = async(jid: string, participant: string | undefined, messageIds: string[], type: MessageReceiptType) => {
81
- const node: BinaryNode = {
82
- tag: 'receipt',
83
- attrs: {
84
- id: messageIds[0],
85
- },
86
- }
87
- const isReadReceipt = type === 'read' || type === 'read-self'
88
- if(isReadReceipt) {
89
- node.attrs.t = unixTimestampSeconds().toString()
90
- }
91
-
92
- if(type === 'sender' && isJidUser(jid)) {
93
- node.attrs.recipient = jid
94
- node.attrs.to = participant!
95
- } else {
96
- node.attrs.to = jid
97
- if(participant) {
98
- node.attrs.participant = participant
99
- }
100
- }
101
-
102
- if(type) {
103
- node.attrs.type = isJidNewsLetter(jid) ? 'read-self' : type
104
- }
105
-
106
- const remainingMessageIds = messageIds.slice(1)
107
- if(remainingMessageIds.length) {
108
- node.content = [
109
- {
110
- tag: 'list',
111
- attrs: { },
112
- content: remainingMessageIds.map(id => ({
113
- tag: 'item',
114
- attrs: { id }
115
- }))
116
- }
117
- ]
118
- }
119
-
120
- logger.debug({ attrs: node.attrs, messageIds }, 'sending receipt for messages')
121
- await sendNode(node)
122
- }
123
-
124
- /** Correctly bulk send receipts to multiple chats, participants */
125
- const sendReceipts = async(keys: WAMessageKey[], type: MessageReceiptType) => {
126
- const recps = aggregateMessageKeysNotFromMe(keys)
127
- for(const { jid, participant, messageIds } of recps) {
128
- await sendReceipt(jid, participant, messageIds, type)
129
- }
130
- }
131
-
132
- /** Bulk read messages. Keys can be from different chats & participants */
133
- const readMessages = async(keys: WAMessageKey[]) => {
134
- const privacySettings = await fetchPrivacySettings()
135
- // based on privacy settings, we have to change the read type
136
- const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self'
137
- await sendReceipts(keys, readType)
138
- }
139
-
140
- /** Fetch all the devices we've to send a message to */
141
- const getUSyncDevices = async(jids: string[], useCache: boolean, ignoreZeroDevices: boolean) => {
142
- const deviceResults: JidWithDevice[] = []
143
-
144
- if(!useCache) {
145
- logger.debug('not using cache for devices')
146
- }
147
-
148
- const users: BinaryNode[] = []
149
- jids = Array.from(new Set(jids))
150
- for(let jid of jids) {
151
- const user = jidDecode(jid)?.user
152
- jid = jidNormalizedUser(jid)
153
-
154
- const devices = userDevicesCache.get<JidWithDevice[]>(user!)
155
- if(devices && useCache) {
156
- deviceResults.push(...devices)
157
-
158
- logger.trace({ user }, 'using cache for devices')
159
- } else {
160
- users.push({ tag: 'user', attrs: { jid } })
161
- }
162
- }
163
-
164
- if(!users.length) {
165
- return deviceResults
166
- }
167
-
168
- const iq: BinaryNode = {
169
- tag: 'iq',
170
- attrs: {
171
- to: S_WHATSAPP_NET,
172
- type: 'get',
173
- xmlns: 'usync',
174
- },
175
- content: [
176
- {
177
- tag: 'usync',
178
- attrs: {
179
- sid: generateMessageTag(),
180
- mode: 'query',
181
- last: 'true',
182
- index: '0',
183
- context: 'message',
184
- },
185
- content: [
186
- {
187
- tag: 'query',
188
- attrs: { },
189
- content: [
190
- {
191
- tag: 'devices',
192
- attrs: { version: '2' }
193
- }
194
- ]
195
- },
196
- { tag: 'list', attrs: { }, content: users }
197
- ]
198
- },
199
- ],
200
- }
201
- const result = await query(iq)
202
- const extracted = extractDeviceJids(result, authState.creds.me!.id, ignoreZeroDevices)
203
- const deviceMap: { [_: string]: JidWithDevice[] } = {}
204
-
205
- for(const item of extracted) {
206
- deviceMap[item.user] = deviceMap[item.user] || []
207
- deviceMap[item.user].push(item)
208
-
209
- deviceResults.push(item)
210
- }
211
-
212
- for(const key in deviceMap) {
213
- userDevicesCache.set(key, deviceMap[key])
214
- }
215
-
216
- return deviceResults
217
- }
218
-
219
-
220
- const assertSessions = async(jids: string[], force: boolean) => {
221
- let didFetchNewSession = false
222
- let jidsRequiringFetch: string[] = []
223
- if(force) {
224
- jidsRequiringFetch = jids
225
- } else {
226
- const addrs = jids.map(jid => (
227
- signalRepository
228
- .jidToSignalProtocolAddress(jid)
229
- ))
230
- const sessions = await authState.keys.get('session', addrs)
231
- for(const jid of jids) {
232
- const signalId = signalRepository
233
- .jidToSignalProtocolAddress(jid)
234
- if(!sessions[signalId]) {
235
- jidsRequiringFetch.push(jid)
236
- }
237
- }
238
- }
239
-
240
- if(jidsRequiringFetch.length) {
241
- logger.debug({ jidsRequiringFetch }, 'fetching sessions')
242
- const result = await query({
243
- tag: 'iq',
244
- attrs: {
245
- xmlns: 'encrypt',
246
- type: 'get',
247
- to: S_WHATSAPP_NET,
248
- },
249
- content: [
250
- {
251
- tag: 'key',
252
- attrs: { },
253
- content: jidsRequiringFetch.map(
254
- jid => ({
255
- tag: 'user',
256
- attrs: { jid },
257
- })
258
- )
259
- }
260
- ]
261
- })
262
- await parseAndInjectE2ESessions(result, signalRepository)
263
-
264
- didFetchNewSession = true
265
- }
266
-
267
- return didFetchNewSession
268
- }
269
-
270
- const createParticipantNodes = async(
271
- jids: string[],
272
- message: proto.IMessage,
273
- extraAttrs?: BinaryNode['attrs']
274
- ) => {
275
- const patched = await patchMessageBeforeSending(message, jids)
276
- const bytes = encodeWAMessage(patched)
277
-
278
- let shouldIncludeDeviceIdentity = false
279
- const nodes = await Promise.all(
280
- jids.map(
281
- async jid => {
282
- const { type, ciphertext } = await signalRepository
283
- .encryptMessage({ jid, data: bytes })
284
- if(type === 'pkmsg') {
285
- shouldIncludeDeviceIdentity = true
286
- }
287
-
288
- const node: BinaryNode = {
289
- tag: 'to',
290
- attrs: { jid },
291
- content: [{
292
- tag: 'enc',
293
- attrs: {
294
- v: '2',
295
- type,
296
- ...extraAttrs || {}
297
- },
298
- content: ciphertext
299
- }]
300
- }
301
- return node
302
- }
303
- )
304
- )
305
- return { nodes, shouldIncludeDeviceIdentity }
306
- } //apela
307
-
308
- const relayMessage = async(
309
- jid: string,
310
- message: proto.IMessage,
311
- { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, cachedGroupMetadata, statusJidList }: MessageRelayOptions
312
- ) => {
313
- const meId = authState.creds.me!.id
314
-
315
- let shouldIncludeDeviceIdentity = false
316
-
317
- const { user, server } = jidDecode(jid)!
318
- const statusJid = 'status@broadcast'
319
- const isGroup = server === 'g.us'
320
- const isStatus = jid === statusJid
321
- const isLid = server === 'lid'
322
- const isNewsletter = server === 'newsletter'
323
-
324
- msgId = msgId || generateMessageID()
325
- useUserDevicesCache = useUserDevicesCache !== false
326
-
327
- const participants: BinaryNode[] = []
328
- const destinationJid = (!isStatus) ? jidEncode(user, isLid ? 'lid' : isGroup ? 'g.us' : isNewsletter ? 'newsletter' : 's.whatsapp.net') : statusJid
329
- const binaryNodeContent: BinaryNode[] = []
330
- const devices: JidWithDevice[] = []
331
-
332
- const meMsg: proto.IMessage = {
333
- deviceSentMessage: {
334
- destinationJid,
335
- message
336
- }
337
- }
338
-
339
- if(participant) {
340
- // when the retry request is not for a group
341
- // only send to the specific device that asked for a retry
342
- // otherwise the message is sent out to every device that should be a recipient
343
- if(!isGroup && !isStatus) {
344
- additionalAttributes = { ...additionalAttributes, 'device_fanout': 'false' }
345
- }
346
-
347
- const { user, device } = jidDecode(participant.jid)!
348
- devices.push({ user, device })
349
- }
350
-
351
- await authState.keys.transaction(
352
- async() => {
353
- const mediaType = getMediaType(message)
354
- if(isGroup || isStatus) {
355
- const [groupData, senderKeyMap] = await Promise.all([
356
- (async() => {
357
- let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined
358
- if(groupData) {
359
- logger.trace({ jid, participants: groupData.participants.length }, 'using cached group metadata')
360
- }
361
-
362
- if(!groupData && !isStatus) {
363
- groupData = await groupMetadata(jid)
364
- }
365
-
366
- return groupData
367
- })(),
368
- (async() => {
369
- if(!participant && !isStatus) {
370
- const result = await authState.keys.get('sender-key-memory', [jid])
371
- return result[jid] || { }
372
- }
373
-
374
- return { }
375
- })()
376
- ])
377
-
378
- if(!participant) {
379
- const participantsList = (groupData && !isStatus) ? groupData.participants.map(p => p.id) : []
380
- if(isStatus && statusJidList) {
381
- participantsList.push(...statusJidList)
382
- }
383
-
384
- const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false)
385
- devices.push(...additionalDevices)
386
- }
387
-
388
- const patched = await patchMessageBeforeSending(message, devices.map(d => jidEncode(d.user, isLid ? 'lid' : 's.whatsapp.net', d.device)))
389
- const bytes = encodeWAMessage(patched)
390
-
391
- const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage(
392
- {
393
- group: destinationJid,
394
- data: bytes,
395
- meId,
396
- }
397
- )
398
-
399
- const senderKeyJids: string[] = []
400
- // ensure a connection is established with every device
401
- for(const { user, device } of devices) {
402
- const jid = jidEncode(user, isLid ? 'lid' : 's.whatsapp.net', device)
403
- if(!senderKeyMap[jid] || !!participant) {
404
- senderKeyJids.push(jid)
405
- // store that this person has had the sender keys sent to them
406
- senderKeyMap[jid] = true
407
- }
408
- }
409
-
410
- // if there are some participants with whom the session has not been established
411
- // if there are, we re-send the senderkey
412
- if(senderKeyJids.length) {
413
- logger.debug({ senderKeyJids }, 'sending new sender key')
414
-
415
- const senderKeyMsg: proto.IMessage = {
416
- senderKeyDistributionMessage: {
417
- axolotlSenderKeyDistributionMessage: senderKeyDistributionMessage,
418
- groupId: destinationJid
419
- }
420
- }
421
-
422
- await assertSessions(senderKeyJids, false)
423
-
424
- const result = await createParticipantNodes(senderKeyJids, senderKeyMsg, mediaType ? { mediatype: mediaType } : undefined)
425
- shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity
426
-
427
- participants.push(...result.nodes)
428
- }
429
-
430
- binaryNodeContent.push({
431
- tag: 'enc',
432
- attrs: { v: '2', type: 'skmsg' },
433
- content: ciphertext
434
- })
435
-
436
- await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } })
437
- } else if (isNewsletter) {
438
- // Message edit
439
- if (message.protocolMessage?.editedMessage) {
440
- msgId = message.protocolMessage.key?.id!
441
- message = message.protocolMessage.editedMessage
442
- }
443
-
444
- // Message delete
445
- if (message.protocolMessage?.type === proto.Message.ProtocolMessage.Type.REVOKE) {
446
- msgId = message.protocolMessage.key?.id!
447
- message = {}
448
- }
449
-
450
- const patched = await patchMessageBeforeSending(message, [])
451
- const bytes = proto.Message.encode(patched).finish()
452
-
453
- binaryNodeContent.push({
454
- tag: 'plaintext',
455
- attrs: mediaType ? { mediatype: mediaType } : {},
456
- content: bytes
457
- })
458
- } else {
459
- const { user: meUser, device: meDevice } = jidDecode(meId)!
460
-
461
- if(!participant) {
462
- devices.push({ user })
463
- // do not send message to self if the device is 0 (mobile)
464
- if(meDevice !== undefined && meDevice !== 0) {
465
- devices.push({ user: meUser })
466
- }
467
-
468
- const additionalDevices = await getUSyncDevices([ meId, jid ], !!useUserDevicesCache, true)
469
- devices.push(...additionalDevices)
470
- }
471
-
472
- const allJids: string[] = []
473
- const meJids: string[] = []
474
- const otherJids: string[] = []
475
- for(const { user, device } of devices) {
476
- const isMe = user === meUser
477
- const jid = jidEncode(isMe && isLid ? authState.creds?.me?.lid!.split(':')[0] || user : user, isLid ? 'lid' : 's.whatsapp.net', device)
478
- if(isMe) {
479
- meJids.push(jid)
480
- } else {
481
- otherJids.push(jid)
482
- }
483
-
484
- allJids.push(jid)
485
- }
486
-
487
- await assertSessions(allJids, false)
488
-
489
- const [
490
- { nodes: meNodes, shouldIncludeDeviceIdentity: s1 },
491
- { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }
492
- ] = await Promise.all([
493
- createParticipantNodes(meJids, meMsg, mediaType ? { mediatype: mediaType } : undefined),
494
- createParticipantNodes(otherJids, message, mediaType ? { mediatype: mediaType } : undefined)
495
- ])
496
- participants.push(...meNodes)
497
- participants.push(...otherNodes)
498
-
499
- shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2
500
- }
501
-
502
- if(participants.length) {
503
- binaryNodeContent.push({
504
- tag: 'participants',
505
- attrs: { },
506
- content: participants
507
- })
508
- }
509
-
510
- const stanza: BinaryNode = {
511
- tag: 'message',
512
- attrs: {
513
- id: msgId!,
514
- type: isNewsletter ? getTypeMessage(message) : 'text',
515
- ...(additionalAttributes || {})
516
- },
517
- content: binaryNodeContent
518
- }
519
-
520
- // if the participant to send to is explicitly specified (generally retry recp)
521
- // ensure the message is only sent to that person
522
- // if a retry receipt is sent to everyone -- it'll fail decryption for everyone else who received the msg
523
- if(participant) {
524
- if(isJidGroup(destinationJid)) {
525
- stanza.attrs.to = destinationJid
526
- stanza.attrs.participant = participant.jid
527
- } else if(areJidsSameUser(participant.jid, meId)) {
528
- stanza.attrs.to = participant.jid
529
- stanza.attrs.recipient = destinationJid
530
- } else {
531
- stanza.attrs.to = participant.jid
532
- }
533
- } else {
534
- stanza.attrs.to = destinationJid
535
- }
536
-
537
- if(shouldIncludeDeviceIdentity) {
538
- (stanza.content as BinaryNode[]).push({
539
- tag: 'device-identity',
540
- attrs: { },
541
- content: encodeSignedDeviceIdentity(authState.creds.account!, true)
542
- })
543
-
544
- logger.debug({ jid }, 'adding device identity')
545
- }
546
-
547
- if(additionalNodes && additionalNodes.length > 0) {
548
- (stanza.content as BinaryNode[]).push(...additionalNodes);
549
- } else {
550
- if((isJidGroup(jid) || isJidUser(jid)) && (message?.viewOnceMessage ? message?.viewOnceMessage : message?.viewOnceMessageV2 ? message?.viewOnceMessageV2 : message?.viewOnceMessageV2Extension ? message?.viewOnceMessageV2Extension : message?.ephemeralMessage ? message?.ephemeralMessage : message?.templateMessage ? message?.templateMessage : message?.interactiveMessage ? message?.interactiveMessage : message?.buttonsMessage)) {
551
- (stanza.content as BinaryNode[]).push({
552
- tag: 'biz',
553
- attrs: {},
554
- content: [{
555
- tag: 'interactive',
556
- attrs: {
557
- type: 'native_flow',
558
- v: '1'
559
- },
560
- content: [{
561
- tag: 'native_flow',
562
- attrs: { name: 'quick_reply' }
563
- }]
564
- }]
565
- });
566
- }
567
- }
568
-
569
- const buttonType = getButtonType(message)
570
- if(buttonType) {
571
- (stanza.content as BinaryNode[]).push({
572
- tag: 'biz',
573
- attrs: { },
574
- content: [
575
- {
576
- tag: buttonType,
577
- attrs: getButtonArgs(message),
578
- }
579
- ]
580
- })
581
-
582
- logger.debug({ jid }, 'adding business node')
583
- }
584
-
585
- logger.debug({ msgId }, `sending message to ${participants.length} devices`)
586
-
587
- await sendNode(stanza)
588
- }
589
- )
590
-
591
- return msgId
592
- }
593
-
594
- const getTypeMessage = (msg: proto.IMessage) => {
595
- if (msg.viewOnceMessage) {
596
- return getTypeMessage(msg.viewOnceMessage.message!)
597
- } else if (msg.viewOnceMessageV2) {
598
- return getTypeMessage(msg.viewOnceMessageV2.message!)
599
- } else if (msg.viewOnceMessageV2Extension) {
600
- return getTypeMessage(msg.viewOnceMessageV2Extension.message!)
601
- } else if (msg.ephemeralMessage) {
602
- return getTypeMessage(msg.ephemeralMessage.message!)
603
- } else if (msg.documentWithCaptionMessage) {
604
- return getTypeMessage(msg.documentWithCaptionMessage.message!)
605
- } else if (msg.reactionMessage) {
606
- return 'reaction'
607
- } else if (msg.pollCreationMessage || msg.pollCreationMessageV2 || msg.pollCreationMessageV3 || msg.pollUpdateMessage) {
608
- return 'reaction'
609
- } else if (getMediaType(msg)) {
610
- return 'media'
611
- } else {
612
- return 'text'
613
- }
614
- }
615
-
616
- const getMediaType = (message: proto.IMessage) => {
617
- if(message.imageMessage) {
618
- return 'image'
619
- } else if(message.videoMessage) {
620
- return message.videoMessage.gifPlayback ? 'gif' : 'video'
621
- } else if(message.audioMessage) {
622
- return message.audioMessage.ptt ? 'ptt' : 'audio'
623
- } else if(message.contactMessage) {
624
- return 'vcard'
625
- } else if(message.documentMessage) {
626
- return 'document'
627
- } else if(message.contactsArrayMessage) {
628
- return 'contact_array'
629
- } else if(message.liveLocationMessage) {
630
- return 'livelocation'
631
- } else if(message.stickerMessage) {
632
- return 'sticker'
633
- } else if(message.listMessage) {
634
- return 'list'
635
- } else if(message.listResponseMessage) {
636
- return 'list_response'
637
- } else if(message.buttonsResponseMessage) {
638
- return 'buttons_response'
639
- } else if(message.orderMessage) {
640
- return 'order'
641
- } else if(message.productMessage) {
642
- return 'product'
643
- } else if(message.interactiveResponseMessage) {
644
- return 'native_flow_response'
645
- }
646
- }
647
-
648
- const getButtonType = (message: proto.IMessage) => {
649
- if(message.buttonsMessage) {
650
- return 'buttons'
651
- } else if(message.buttonsResponseMessage) {
652
- return 'buttons_response'
653
- } else if(message.interactiveResponseMessage) {
654
- return 'interactive_response'
655
- } else if(message.listMessage) {
656
- return 'list'
657
- } else if(message.listResponseMessage) {
658
- return 'list_response'
659
- }
660
- }
661
-
662
- const getButtonArgs = (message: proto.IMessage): BinaryNode['attrs'] => {
663
- if(message.templateMessage) {
664
- // TODO: Add attributes
665
- return {}
666
- } else if(message.listMessage) {
667
- const type = message.listMessage.listType
668
- if(!type) {
669
- throw new Boom('Expected list type inside message')
670
- }
671
-
672
- return { v: '2', type: ListType[type].toLowerCase() }
673
- } else {
674
- return {}
675
- }
676
- }
677
-
678
- const getPrivacyTokens = async(jids: string[]) => {
679
- const t = unixTimestampSeconds().toString()
680
- const result = await query({
681
- tag: 'iq',
682
- attrs: {
683
- to: S_WHATSAPP_NET,
684
- type: 'set',
685
- xmlns: 'privacy'
686
- },
687
- content: [
688
- {
689
- tag: 'tokens',
690
- attrs: { },
691
- content: jids.map(
692
- jid => ({
693
- tag: 'token',
694
- attrs: {
695
- jid: jidNormalizedUser(jid),
696
- t,
697
- type: 'trusted_contact'
698
- }
699
- })
700
- )
701
- }
702
- ]
703
- })
704
-
705
- return result
706
- }
707
-
708
- const waUploadToServer = getWAUploadToServer(config, refreshMediaConn)
709
-
710
- const waitForMsgMediaUpdate = bindWaitForEvent(ev, 'messages.media-update')
711
-
712
- return {
713
- ...sock,
714
- getPrivacyTokens,
715
- assertSessions,
716
- relayMessage,
717
- sendReceipt,
718
- sendReceipts,
719
- getButtonArgs,
720
- readMessages,
721
- refreshMediaConn,
722
- getUSyncDevices,
723
- createParticipantNodes,
724
- waUploadToServer,
725
- fetchPrivacySettings,
726
- updateMediaMessage: async(message: proto.IWebMessageInfo) => {
727
- const content = assertMediaContent(message.message)
728
- const mediaKey = content.mediaKey!
729
- const meId = authState.creds.me!.id
730
- const node = encryptMediaRetryRequest(message.key, mediaKey, meId)
731
-
732
- let error: Error | undefined = undefined
733
- await Promise.all(
734
- [
735
- sendNode(node),
736
- waitForMsgMediaUpdate(update => {
737
- const result = update.find(c => c.key.id === message.key.id)
738
- if(result) {
739
- if(result.error) {
740
- error = result.error
741
- } else {
742
- try {
743
- const media = decryptMediaRetryData(result.media!, mediaKey, result.key.id!)
744
- if(media.result !== proto.MediaRetryNotification.ResultType.SUCCESS) {
745
- const resultStr = proto.MediaRetryNotification.ResultType[media.result]
746
- throw new Boom(
747
- `Media re-upload failed by device (${resultStr})`,
748
- { data: media, statusCode: getStatusCodeForMediaRetry(media.result) || 404 }
749
- )
750
- }
751
-
752
- content.directPath = media.directPath
753
- content.url = getUrlFromDirectPath(content.directPath!)
754
-
755
- logger.debug({ directPath: media.directPath, key: result.key }, 'media update successful')
756
- } catch(err) {
757
- error = err
758
- }
759
- }
760
-
761
- return true
762
- }
763
- })
764
- ]
765
- )
766
-
767
- if(error) {
768
- throw error
769
- }
770
-
771
- ev.emit('messages.update', [
772
- { key: message.key, update: { message: message.message } }
773
- ])
774
-
775
- return message
776
- },
777
- sendMessage: async(
778
- jid: string,
779
- content: AnyMessageContent,
780
- options: MiscMessageGenerationOptions = { }
781
- ) => {
782
- const userJid = authState.creds.me!.id
783
- if(
784
- typeof content === 'object' &&
785
- 'disappearingMessagesInChat' in content &&
786
- typeof content['disappearingMessagesInChat'] !== 'undefined' &&
787
- isJidGroup(jid)
788
- ) {
789
- const { disappearingMessagesInChat } = content
790
- const value = typeof disappearingMessagesInChat === 'boolean' ?
791
- (disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) :
792
- disappearingMessagesInChat
793
- await groupToggleEphemeral(jid, value)
794
- } else {
795
- let mediaHandle
796
- const fullMsg = await generateWAMessage(
797
- jid,
798
- content,
799
- {
800
- logger,
801
- userJid,
802
- getUrlInfo: text => getUrlInfo(
803
- text,
804
- {
805
- thumbnailWidth: linkPreviewImageThumbnailWidth,
806
- fetchOpts: {
807
- timeout: 3_000,
808
- ...axiosOptions || { }
809
- },
810
- logger,
811
- uploadImage: generateHighQualityLinkPreview
812
- ? waUploadToServer
813
- : undefined
814
- },
815
- ),
816
- upload: async(readStream: Readable, opts: WAMediaUploadFunctionOpts) => {
817
- const up = await waUploadToServer(readStream, { ...opts, newsletter: isJidNewsLetter(jid) })
818
- mediaHandle = up.handle
819
- return up
820
- },
821
- mediaCache: config.mediaCache,
822
- options: config.options,
823
- ...options,
824
- }
825
- )
826
- const isDeleteMsg = 'delete' in content && !!content.delete
827
- const isEditMsg = 'edit' in content && !!content.edit
828
- const isAiMsg = 'ai' in content && !!content.ai
829
- const additionalAttributes: BinaryNodeAttributes = { }
830
- const additionalNodes = []
831
- // required for delete
832
- if(isDeleteMsg) {
833
- // if the chat is a group, and I am not the author, then delete the message as an admin
834
- if((isJidGroup(content.delete?.remoteJid as string) && !content.delete?.fromMe) || isJidNewsLetter(jid)) {
835
- additionalAttributes.edit = '8'
836
- } else {
837
- additionalAttributes.edit = '7'
838
- }
839
- } else if(isEditMsg) {
840
- additionalAttributes.edit = isJidNewsLetter(jid) ? '3' : '1'
841
- } else if(isAiMsg) {
842
- (additionalNodes as BinaryNode[]).push({
843
- attrs: {
844
- biz_bot: '1'
845
- },
846
- tag: "bot"
847
- })
848
- }
849
-
850
- if (mediaHandle) {
851
- additionalAttributes['media_id'] = mediaHandle
852
- }
853
-
854
- if('cachedGroupMetadata' in options) {
855
- console.warn('cachedGroupMetadata in sendMessage are deprecated, now cachedGroupMetadata is part of the socket config.')
856
- }
857
-
858
- await relayMessage(jid, fullMsg.message!, { messageId: fullMsg.key.id!, cachedGroupMetadata: options.cachedGroupMetadata, additionalNodes: isAiMsg ? additionalNodes : options.additionalNodes, additionalAttributes, statusJidList: options.statusJidList })
859
- if(config.emitOwnEvents) {
860
- process.nextTick(() => {
861
- processingMutex.mutex(() => (
862
- upsertMessage(fullMsg, 'append')
863
- ))
864
- })
865
- }
866
-
867
- return fullMsg
868
- }
869
- }
870
- }
871
- }