gifted-baileys 1.5.4 → 1.5.6

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/LICENSE +1 -1
  2. package/WAProto/WAProto.proto +88 -969
  3. package/WAProto/index.d.ts +1256 -13195
  4. package/WAProto/index.js +74730 -125106
  5. package/package.json +9 -27
  6. package/src/Defaults/baileys-version.json +3 -0
  7. package/{lib → src}/Defaults/index.js +14 -7
  8. package/src/Defaults/index.ts +131 -0
  9. package/src/README.md +1 -0
  10. package/src/Signal/libsignal.js +180 -0
  11. package/src/Signal/libsignal.ts +141 -0
  12. package/src/Socket/Client/abstract-socket-client.ts +19 -0
  13. package/{lib → src}/Socket/Client/index.js +3 -2
  14. package/src/Socket/Client/index.ts +3 -0
  15. package/src/Socket/Client/mobile-socket-client.js +78 -0
  16. package/src/Socket/Client/mobile-socket-client.ts +66 -0
  17. package/src/Socket/Client/web-socket-client.js +75 -0
  18. package/src/Socket/Client/web-socket-client.ts +57 -0
  19. package/{lib → src}/Socket/business.js +33 -28
  20. package/src/Socket/business.ts +281 -0
  21. package/{lib → src}/Socket/chats.js +176 -174
  22. package/src/Socket/chats.ts +1030 -0
  23. package/{lib → src}/Socket/groups.js +68 -80
  24. package/src/Socket/groups.ts +356 -0
  25. package/{lib → src}/Socket/index.js +1 -4
  26. package/src/Socket/index.ts +13 -0
  27. package/{lib → src}/Socket/messages-recv.js +211 -378
  28. package/src/Socket/messages-recv.ts +985 -0
  29. package/{lib → src}/Socket/messages-send.js +177 -452
  30. package/src/Socket/messages-send.ts +871 -0
  31. package/{lib → src}/Socket/newsletter.js +98 -107
  32. package/src/Socket/newsletter.ts +282 -0
  33. package/{lib → src}/Socket/registration.js +48 -56
  34. package/src/Socket/registration.ts +250 -0
  35. package/{lib → src}/Socket/socket.js +77 -77
  36. package/src/Socket/socket.ts +777 -0
  37. package/src/Store/index.ts +3 -0
  38. package/{lib → src}/Store/make-cache-manager-store.js +34 -25
  39. package/src/Store/make-cache-manager-store.ts +100 -0
  40. package/{lib → src}/Store/make-in-memory-store.js +32 -36
  41. package/src/Store/make-in-memory-store.ts +475 -0
  42. package/src/Store/make-ordered-dictionary.ts +86 -0
  43. package/{lib → src}/Store/object-repository.js +1 -1
  44. package/src/Store/object-repository.ts +32 -0
  45. package/src/Tests/test.app-state-sync.js +204 -0
  46. package/src/Tests/test.app-state-sync.ts +207 -0
  47. package/src/Tests/test.event-buffer.js +270 -0
  48. package/src/Tests/test.event-buffer.ts +319 -0
  49. package/src/Tests/test.key-store.js +76 -0
  50. package/src/Tests/test.key-store.ts +92 -0
  51. package/src/Tests/test.libsignal.js +141 -0
  52. package/src/Tests/test.libsignal.ts +186 -0
  53. package/src/Tests/test.media-download.js +93 -0
  54. package/src/Tests/test.media-download.ts +76 -0
  55. package/src/Tests/test.messages.js +33 -0
  56. package/src/Tests/test.messages.ts +37 -0
  57. package/src/Tests/utils.js +34 -0
  58. package/src/Tests/utils.ts +36 -0
  59. package/src/Types/Auth.ts +113 -0
  60. package/src/Types/Call.ts +15 -0
  61. package/src/Types/Chat.ts +106 -0
  62. package/{lib/Types/Contact.d.ts → src/Types/Contact.ts} +9 -8
  63. package/src/Types/Events.ts +93 -0
  64. package/src/Types/GroupMetadata.ts +53 -0
  65. package/src/Types/Label.ts +36 -0
  66. package/{lib/Types/LabelAssociation.d.ts → src/Types/LabelAssociation.ts} +22 -16
  67. package/src/Types/Message.ts +288 -0
  68. package/src/Types/Newsletter.ts +98 -0
  69. package/src/Types/Product.ts +85 -0
  70. package/src/Types/Signal.ts +68 -0
  71. package/{lib/Types/Socket.d.ts → src/Types/Socket.ts} +68 -61
  72. package/src/Types/State.ts +29 -0
  73. package/src/Types/index.ts +59 -0
  74. package/{lib → src}/Utils/auth-utils.js +90 -73
  75. package/src/Utils/auth-utils.ts +222 -0
  76. package/src/Utils/baileys-event-stream.js +92 -0
  77. package/src/Utils/baileys-event-stream.ts +66 -0
  78. package/{lib → src}/Utils/business.js +43 -15
  79. package/src/Utils/business.ts +275 -0
  80. package/{lib → src}/Utils/chat-utils.js +94 -87
  81. package/src/Utils/chat-utils.ts +860 -0
  82. package/{lib → src}/Utils/crypto.js +2 -4
  83. package/src/Utils/crypto.ts +131 -0
  84. package/src/Utils/decode-wa-message.js +211 -0
  85. package/src/Utils/decode-wa-message.ts +228 -0
  86. package/{lib → src}/Utils/event-buffer.js +13 -4
  87. package/src/Utils/event-buffer.ts +613 -0
  88. package/{lib → src}/Utils/generics.js +86 -67
  89. package/src/Utils/generics.ts +434 -0
  90. package/{lib → src}/Utils/history.js +39 -13
  91. package/src/Utils/history.ts +112 -0
  92. package/src/Utils/index.ts +17 -0
  93. package/{lib → src}/Utils/link-preview.js +54 -17
  94. package/src/Utils/link-preview.ts +122 -0
  95. package/src/Utils/logger.ts +3 -0
  96. package/src/Utils/lt-hash.ts +61 -0
  97. package/{lib → src}/Utils/make-mutex.js +13 -4
  98. package/src/Utils/make-mutex.ts +44 -0
  99. package/{lib → src}/Utils/messages-media.js +255 -193
  100. package/src/Utils/messages-media.ts +847 -0
  101. package/{lib → src}/Utils/messages.js +118 -588
  102. package/src/Utils/messages.ts +956 -0
  103. package/src/Utils/noise-handler.ts +197 -0
  104. package/{lib → src}/Utils/process-message.js +30 -27
  105. package/src/Utils/process-message.ts +414 -0
  106. package/{lib → src}/Utils/signal.js +42 -25
  107. package/src/Utils/signal.ts +177 -0
  108. package/{lib → src}/Utils/use-multi-file-auth-state.js +28 -27
  109. package/src/Utils/use-multi-file-auth-state.ts +90 -0
  110. package/{lib → src}/Utils/validate-connection.js +9 -40
  111. package/src/Utils/validate-connection.ts +238 -0
  112. package/src/WABinary/constants.ts +42 -0
  113. package/src/WABinary/decode.ts +265 -0
  114. package/{lib → src}/WABinary/encode.js +10 -16
  115. package/src/WABinary/encode.ts +236 -0
  116. package/src/WABinary/generic-utils.ts +121 -0
  117. package/src/WABinary/index.ts +5 -0
  118. package/src/WABinary/jid-utils.ts +68 -0
  119. package/src/WABinary/types.ts +17 -0
  120. package/src/WAM/BinaryInfo.ts +12 -0
  121. package/src/WAM/constants.ts +15382 -0
  122. package/src/WAM/encode.ts +174 -0
  123. package/src/WAM/index.ts +3 -0
  124. package/{lib → src}/index.js +0 -1
  125. package/src/index.ts +13 -0
  126. package/README.md +0 -1645
  127. package/lib/Defaults/baileys-version.json +0 -3
  128. package/lib/Defaults/index.d.ts +0 -284
  129. package/lib/Signal/libsignal.d.ts +0 -3
  130. package/lib/Signal/libsignal.js +0 -161
  131. package/lib/Socket/Client/abstract-socket-client.d.ts +0 -15
  132. package/lib/Socket/Client/index.d.ts +0 -2
  133. package/lib/Socket/Client/mobile-socket-client.d.ts +0 -12
  134. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  135. package/lib/Socket/Client/types.d.ts +0 -17
  136. package/lib/Socket/Client/types.js +0 -13
  137. package/lib/Socket/Client/websocket.d.ts +0 -12
  138. package/lib/Socket/Client/websocket.js +0 -62
  139. package/lib/Socket/business.d.ts +0 -170
  140. package/lib/Socket/chats.d.ts +0 -81
  141. package/lib/Socket/groups.d.ts +0 -115
  142. package/lib/Socket/index.d.ts +0 -172
  143. package/lib/Socket/messages-recv.d.ts +0 -158
  144. package/lib/Socket/messages-send.d.ts +0 -155
  145. package/lib/Socket/newsletter.d.ts +0 -132
  146. package/lib/Socket/registration.d.ts +0 -264
  147. package/lib/Socket/socket.d.ts +0 -44
  148. package/lib/Socket/usync.d.ts +0 -37
  149. package/lib/Socket/usync.js +0 -70
  150. package/lib/Store/index.d.ts +0 -3
  151. package/lib/Store/make-cache-manager-store.d.ts +0 -14
  152. package/lib/Store/make-in-memory-store.d.ts +0 -118
  153. package/lib/Store/make-ordered-dictionary.d.ts +0 -13
  154. package/lib/Store/object-repository.d.ts +0 -10
  155. package/lib/Types/Auth.d.ts +0 -109
  156. package/lib/Types/Call.d.ts +0 -13
  157. package/lib/Types/Chat.d.ts +0 -107
  158. package/lib/Types/Events.d.ts +0 -172
  159. package/lib/Types/GroupMetadata.d.ts +0 -56
  160. package/lib/Types/Label.d.ts +0 -46
  161. package/lib/Types/Message.d.ts +0 -433
  162. package/lib/Types/Newsletter.d.ts +0 -92
  163. package/lib/Types/Product.d.ts +0 -78
  164. package/lib/Types/Signal.d.ts +0 -57
  165. package/lib/Types/State.d.ts +0 -27
  166. package/lib/Types/USync.d.ts +0 -25
  167. package/lib/Types/USync.js +0 -2
  168. package/lib/Types/index.d.ts +0 -66
  169. package/lib/Utils/auth-utils.d.ts +0 -18
  170. package/lib/Utils/baileys-event-stream.d.ts +0 -16
  171. package/lib/Utils/baileys-event-stream.js +0 -63
  172. package/lib/Utils/business.d.ts +0 -22
  173. package/lib/Utils/chat-utils.d.ts +0 -70
  174. package/lib/Utils/crypto.d.ts +0 -40
  175. package/lib/Utils/decode-wa-message.d.ts +0 -36
  176. package/lib/Utils/decode-wa-message.js +0 -226
  177. package/lib/Utils/event-buffer.d.ts +0 -35
  178. package/lib/Utils/generics.d.ts +0 -88
  179. package/lib/Utils/history.d.ts +0 -19
  180. package/lib/Utils/index.d.ts +0 -17
  181. package/lib/Utils/link-preview.d.ts +0 -21
  182. package/lib/Utils/logger.d.ts +0 -2
  183. package/lib/Utils/lt-hash.d.ts +0 -12
  184. package/lib/Utils/make-mutex.d.ts +0 -7
  185. package/lib/Utils/messages-media.d.ts +0 -113
  186. package/lib/Utils/messages.d.ts +0 -77
  187. package/lib/Utils/noise-handler.d.ts +0 -20
  188. package/lib/Utils/process-message.d.ts +0 -41
  189. package/lib/Utils/signal.d.ts +0 -33
  190. package/lib/Utils/use-multi-file-auth-state.d.ts +0 -12
  191. package/lib/Utils/validate-connection.d.ts +0 -11
  192. package/lib/WABinary/constants.d.ts +0 -27
  193. package/lib/WABinary/decode.d.ts +0 -6
  194. package/lib/WABinary/encode.d.ts +0 -2
  195. package/lib/WABinary/generic-utils.d.ts +0 -14
  196. package/lib/WABinary/index.d.ts +0 -5
  197. package/lib/WABinary/jid-utils.d.ts +0 -31
  198. package/lib/WABinary/types.d.ts +0 -18
  199. package/lib/WAM/BinaryInfo.d.ts +0 -8
  200. package/lib/WAM/constants.d.ts +0 -38
  201. package/lib/WAM/encode.d.ts +0 -2
  202. package/lib/WAM/index.d.ts +0 -3
  203. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -9
  204. package/lib/WAUSync/Protocols/USyncContactProtocol.js +0 -32
  205. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -22
  206. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +0 -57
  207. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -12
  208. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +0 -30
  209. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -12
  210. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +0 -42
  211. package/lib/WAUSync/Protocols/index.d.ts +0 -4
  212. package/lib/WAUSync/Protocols/index.js +0 -20
  213. package/lib/WAUSync/USyncQuery.d.ts +0 -26
  214. package/lib/WAUSync/USyncQuery.js +0 -79
  215. package/lib/WAUSync/USyncUser.d.ts +0 -10
  216. package/lib/WAUSync/USyncUser.js +0 -22
  217. package/lib/WAUSync/index.d.ts +0 -3
  218. package/lib/WAUSync/index.js +0 -19
  219. /package/{lib → src}/Defaults/phonenumber-mcc.json +0 -0
  220. /package/{lib → src}/Socket/Client/abstract-socket-client.js +0 -0
  221. /package/{lib → src}/Store/index.js +0 -0
  222. /package/{lib → src}/Store/make-ordered-dictionary.js +0 -0
  223. /package/{lib → src}/Types/Auth.js +0 -0
  224. /package/{lib → src}/Types/Call.js +0 -0
  225. /package/{lib → src}/Types/Chat.js +0 -0
  226. /package/{lib → src}/Types/Contact.js +0 -0
  227. /package/{lib → src}/Types/Events.js +0 -0
  228. /package/{lib → src}/Types/GroupMetadata.js +0 -0
  229. /package/{lib → src}/Types/Label.js +0 -0
  230. /package/{lib → src}/Types/LabelAssociation.js +0 -0
  231. /package/{lib → src}/Types/Message.js +0 -0
  232. /package/{lib → src}/Types/Newsletter.js +0 -0
  233. /package/{lib → src}/Types/Product.js +0 -0
  234. /package/{lib → src}/Types/Signal.js +0 -0
  235. /package/{lib → src}/Types/Socket.js +0 -0
  236. /package/{lib → src}/Types/State.js +0 -0
  237. /package/{lib → src}/Types/index.js +0 -0
  238. /package/{lib → src}/Utils/index.js +0 -0
  239. /package/{lib → src}/Utils/logger.js +0 -0
  240. /package/{lib → src}/Utils/lt-hash.js +0 -0
  241. /package/{lib → src}/Utils/noise-handler.js +0 -0
  242. /package/{lib → src}/WABinary/constants.js +0 -0
  243. /package/{lib → src}/WABinary/decode.js +0 -0
  244. /package/{lib → src}/WABinary/generic-utils.js +0 -0
  245. /package/{lib → src}/WABinary/index.js +0 -0
  246. /package/{lib → src}/WABinary/jid-utils.js +0 -0
  247. /package/{lib → src}/WABinary/types.js +0 -0
  248. /package/{lib → src}/WAM/BinaryInfo.js +0 -0
  249. /package/{lib → src}/WAM/constants.js +0 -0
  250. /package/{lib → src}/WAM/encode.js +0 -0
  251. /package/{lib → src}/WAM/index.js +0 -0
  252. /package/{lib → src}/gifted +0 -0
@@ -1,4 +1,20 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
12
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
13
+ var m = o[Symbol.asyncIterator], i;
14
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
15
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
16
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
17
+ };
2
18
  Object.defineProperty(exports, "__esModule", { value: true });
3
19
  exports.uploadingNecessaryImages = exports.parseProductNode = exports.toProductNode = exports.parseOrderDetailsNode = exports.parseCollectionsNode = exports.parseCatalogNode = void 0;
4
20
  exports.uploadingNecessaryImagesOfProduct = uploadingNecessaryImagesOfProduct;
@@ -182,41 +198,53 @@ exports.parseProductNode = parseProductNode;
182
198
  /**
183
199
  * Uploads images not already uploaded to WA's servers
184
200
  */
185
- async function uploadingNecessaryImagesOfProduct(product, waUploadToServer, timeoutMs = 30000) {
186
- product = {
187
- ...product,
188
- images: product.images ? await (0, exports.uploadingNecessaryImages)(product.images, waUploadToServer, timeoutMs) : product.images
189
- };
190
- return product;
201
+ function uploadingNecessaryImagesOfProduct(product_1, waUploadToServer_1) {
202
+ return __awaiter(this, arguments, void 0, function* (product, waUploadToServer, timeoutMs = 30000) {
203
+ product = Object.assign(Object.assign({}, product), { images: product.images ? yield (0, exports.uploadingNecessaryImages)(product.images, waUploadToServer, timeoutMs) : product.images });
204
+ return product;
205
+ });
191
206
  }
192
207
  /**
193
208
  * Uploads images not already uploaded to WA's servers
194
209
  */
195
- const uploadingNecessaryImages = async (images, waUploadToServer, timeoutMs = 30000) => {
196
- const results = await Promise.all(images.map(async (img) => {
210
+ const uploadingNecessaryImages = (images_1, waUploadToServer_1, ...args_1) => __awaiter(void 0, [images_1, waUploadToServer_1, ...args_1], void 0, function* (images, waUploadToServer, timeoutMs = 30000) {
211
+ const results = yield Promise.all(images.map((img) => __awaiter(void 0, void 0, void 0, function* () {
212
+ var _a, e_1, _b, _c;
197
213
  if ('url' in img) {
198
214
  const url = img.url.toString();
199
215
  if (url.includes('.whatsapp.net')) {
200
216
  return { url };
201
217
  }
202
218
  }
203
- const { stream } = await (0, messages_media_1.getStream)(img);
219
+ const { stream } = yield (0, messages_media_1.getStream)(img);
204
220
  const hasher = (0, crypto_1.createHash)('sha256');
205
221
  const contentBlocks = [];
206
- for await (const block of stream) {
207
- hasher.update(block);
208
- contentBlocks.push(block);
222
+ try {
223
+ for (var _d = true, stream_1 = __asyncValues(stream), stream_1_1; stream_1_1 = yield stream_1.next(), _a = stream_1_1.done, !_a; _d = true) {
224
+ _c = stream_1_1.value;
225
+ _d = false;
226
+ const block = _c;
227
+ hasher.update(block);
228
+ contentBlocks.push(block);
229
+ }
230
+ }
231
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
232
+ finally {
233
+ try {
234
+ if (!_d && !_a && (_b = stream_1.return)) yield _b.call(stream_1);
235
+ }
236
+ finally { if (e_1) throw e_1.error; }
209
237
  }
210
238
  const sha = hasher.digest('base64');
211
- const { directPath } = await waUploadToServer((0, messages_media_1.toReadable)(Buffer.concat(contentBlocks)), {
239
+ const { directPath } = yield waUploadToServer((0, messages_media_1.toReadable)(Buffer.concat(contentBlocks)), {
212
240
  mediaType: 'product-catalog-image',
213
241
  fileEncSha256B64: sha,
214
242
  timeoutMs
215
243
  });
216
244
  return { url: (0, messages_media_1.getUrlFromDirectPath)(directPath) };
217
- }));
245
+ })));
218
246
  return results;
219
- };
247
+ });
220
248
  exports.uploadingNecessaryImages = uploadingNecessaryImages;
221
249
  const parseImageUrls = (mediaNode) => {
222
250
  const imgNode = (0, WABinary_1.getBinaryNodeChild)(mediaNode, 'image');
@@ -0,0 +1,275 @@
1
+ import { Boom } from '@hapi/boom'
2
+ import { createHash } from 'crypto'
3
+ import { CatalogCollection, CatalogStatus, OrderDetails, OrderProduct, Product, ProductCreate, ProductUpdate, WAMediaUpload, WAMediaUploadFunction } from '../Types'
4
+ import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString } from '../WABinary'
5
+ import { getStream, getUrlFromDirectPath, toReadable } from './messages-media'
6
+
7
+ export const parseCatalogNode = (node: BinaryNode) => {
8
+ const catalogNode = getBinaryNodeChild(node, 'product_catalog')
9
+ const products = getBinaryNodeChildren(catalogNode, 'product').map(parseProductNode)
10
+ const paging = getBinaryNodeChild(catalogNode, 'paging')
11
+
12
+ return {
13
+ products,
14
+ nextPageCursor: paging
15
+ ? getBinaryNodeChildString(paging, 'after')
16
+ : undefined
17
+ }
18
+ }
19
+
20
+ export const parseCollectionsNode = (node: BinaryNode) => {
21
+ const collectionsNode = getBinaryNodeChild(node, 'collections')
22
+ const collections = getBinaryNodeChildren(collectionsNode, 'collection').map<CatalogCollection>(
23
+ collectionNode => {
24
+ const id = getBinaryNodeChildString(collectionNode, 'id')!
25
+ const name = getBinaryNodeChildString(collectionNode, 'name')!
26
+
27
+ const products = getBinaryNodeChildren(collectionNode, 'product').map(parseProductNode)
28
+ return {
29
+ id,
30
+ name,
31
+ products,
32
+ status: parseStatusInfo(collectionNode)
33
+ }
34
+ }
35
+ )
36
+
37
+ return {
38
+ collections
39
+ }
40
+ }
41
+
42
+ export const parseOrderDetailsNode = (node: BinaryNode) => {
43
+ const orderNode = getBinaryNodeChild(node, 'order')
44
+ const products = getBinaryNodeChildren(orderNode, 'product').map<OrderProduct>(
45
+ productNode => {
46
+ const imageNode = getBinaryNodeChild(productNode, 'image')!
47
+ return {
48
+ id: getBinaryNodeChildString(productNode, 'id')!,
49
+ name: getBinaryNodeChildString(productNode, 'name')!,
50
+ imageUrl: getBinaryNodeChildString(imageNode, 'url')!,
51
+ price: +getBinaryNodeChildString(productNode, 'price')!,
52
+ currency: getBinaryNodeChildString(productNode, 'currency')!,
53
+ quantity: +getBinaryNodeChildString(productNode, 'quantity')!
54
+ }
55
+ }
56
+ )
57
+
58
+ const priceNode = getBinaryNodeChild(orderNode, 'price')
59
+
60
+ const orderDetails: OrderDetails = {
61
+ price: {
62
+ total: +getBinaryNodeChildString(priceNode, 'total')!,
63
+ currency: getBinaryNodeChildString(priceNode, 'currency')!,
64
+ },
65
+ products
66
+ }
67
+
68
+ return orderDetails
69
+ }
70
+
71
+ export const toProductNode = (productId: string | undefined, product: ProductCreate | ProductUpdate) => {
72
+ const attrs: BinaryNode['attrs'] = { }
73
+ const content: BinaryNode[] = [ ]
74
+
75
+ if(typeof productId !== 'undefined') {
76
+ content.push({
77
+ tag: 'id',
78
+ attrs: { },
79
+ content: Buffer.from(productId)
80
+ })
81
+ }
82
+
83
+ if(typeof product.name !== 'undefined') {
84
+ content.push({
85
+ tag: 'name',
86
+ attrs: { },
87
+ content: Buffer.from(product.name)
88
+ })
89
+ }
90
+
91
+ if(typeof product.description !== 'undefined') {
92
+ content.push({
93
+ tag: 'description',
94
+ attrs: { },
95
+ content: Buffer.from(product.description)
96
+ })
97
+ }
98
+
99
+ if(typeof product.retailerId !== 'undefined') {
100
+ content.push({
101
+ tag: 'retailer_id',
102
+ attrs: { },
103
+ content: Buffer.from(product.retailerId)
104
+ })
105
+ }
106
+
107
+ if(product.images.length) {
108
+ content.push({
109
+ tag: 'media',
110
+ attrs: { },
111
+ content: product.images.map(
112
+ img => {
113
+ if(!('url' in img)) {
114
+ throw new Boom('Expected img for product to already be uploaded', { statusCode: 400 })
115
+ }
116
+
117
+ return {
118
+ tag: 'image',
119
+ attrs: { },
120
+ content: [
121
+ {
122
+ tag: 'url',
123
+ attrs: { },
124
+ content: Buffer.from(img.url.toString())
125
+ }
126
+ ]
127
+ }
128
+ }
129
+ )
130
+ })
131
+ }
132
+
133
+ if(typeof product.price !== 'undefined') {
134
+ content.push({
135
+ tag: 'price',
136
+ attrs: { },
137
+ content: Buffer.from(product.price.toString())
138
+ })
139
+ }
140
+
141
+ if(typeof product.currency !== 'undefined') {
142
+ content.push({
143
+ tag: 'currency',
144
+ attrs: { },
145
+ content: Buffer.from(product.currency)
146
+ })
147
+ }
148
+
149
+ if('originCountryCode' in product) {
150
+ if(typeof product.originCountryCode === 'undefined') {
151
+ attrs['compliance_category'] = 'COUNTRY_ORIGIN_EXEMPT'
152
+ } else {
153
+ content.push({
154
+ tag: 'compliance_info',
155
+ attrs: { },
156
+ content: [
157
+ {
158
+ tag: 'country_code_origin',
159
+ attrs: { },
160
+ content: Buffer.from(product.originCountryCode)
161
+ }
162
+ ]
163
+ })
164
+ }
165
+ }
166
+
167
+
168
+ if(typeof product.isHidden !== 'undefined') {
169
+ attrs['is_hidden'] = product.isHidden.toString()
170
+ }
171
+
172
+ const node: BinaryNode = {
173
+ tag: 'product',
174
+ attrs,
175
+ content
176
+ }
177
+ return node
178
+ }
179
+
180
+ export const parseProductNode = (productNode: BinaryNode) => {
181
+ const isHidden = productNode.attrs.is_hidden === 'true'
182
+ const id = getBinaryNodeChildString(productNode, 'id')!
183
+
184
+ const mediaNode = getBinaryNodeChild(productNode, 'media')!
185
+ const statusInfoNode = getBinaryNodeChild(productNode, 'status_info')!
186
+
187
+ const product: Product = {
188
+ id,
189
+ imageUrls: parseImageUrls(mediaNode),
190
+ reviewStatus: {
191
+ whatsapp: getBinaryNodeChildString(statusInfoNode, 'status')!,
192
+ },
193
+ availability: 'in stock',
194
+ name: getBinaryNodeChildString(productNode, 'name')!,
195
+ retailerId: getBinaryNodeChildString(productNode, 'retailer_id'),
196
+ url: getBinaryNodeChildString(productNode, 'url'),
197
+ description: getBinaryNodeChildString(productNode, 'description')!,
198
+ price: +getBinaryNodeChildString(productNode, 'price')!,
199
+ currency: getBinaryNodeChildString(productNode, 'currency')!,
200
+ isHidden,
201
+ }
202
+
203
+ return product
204
+ }
205
+
206
+ /**
207
+ * Uploads images not already uploaded to WA's servers
208
+ */
209
+ export async function uploadingNecessaryImagesOfProduct<T extends ProductUpdate | ProductCreate>(product: T, waUploadToServer: WAMediaUploadFunction, timeoutMs = 30_000) {
210
+ product = {
211
+ ...product,
212
+ images: product.images ? await uploadingNecessaryImages(product.images, waUploadToServer, timeoutMs) : product.images
213
+ }
214
+ return product
215
+ }
216
+
217
+ /**
218
+ * Uploads images not already uploaded to WA's servers
219
+ */
220
+ export const uploadingNecessaryImages = async(
221
+ images: WAMediaUpload[],
222
+ waUploadToServer: WAMediaUploadFunction,
223
+ timeoutMs = 30_000
224
+ ) => {
225
+ const results = await Promise.all(
226
+ images.map<Promise<{ url: string }>>(
227
+ async img => {
228
+
229
+ if('url' in img) {
230
+ const url = img.url.toString()
231
+ if(url.includes('.whatsapp.net')) {
232
+ return { url }
233
+ }
234
+ }
235
+
236
+ const { stream } = await getStream(img)
237
+ const hasher = createHash('sha256')
238
+ const contentBlocks: Buffer[] = []
239
+ for await (const block of stream) {
240
+ hasher.update(block)
241
+ contentBlocks.push(block)
242
+ }
243
+
244
+ const sha = hasher.digest('base64')
245
+
246
+ const { directPath } = await waUploadToServer(
247
+ toReadable(Buffer.concat(contentBlocks)),
248
+ {
249
+ mediaType: 'product-catalog-image',
250
+ fileEncSha256B64: sha,
251
+ timeoutMs
252
+ }
253
+ )
254
+ return { url: getUrlFromDirectPath(directPath) }
255
+ }
256
+ )
257
+ )
258
+ return results
259
+ }
260
+
261
+ const parseImageUrls = (mediaNode: BinaryNode) => {
262
+ const imgNode = getBinaryNodeChild(mediaNode, 'image')
263
+ return {
264
+ requested: getBinaryNodeChildString(imgNode, 'request_image_url')!,
265
+ original: getBinaryNodeChildString(imgNode, 'original_image_url')!
266
+ }
267
+ }
268
+
269
+ const parseStatusInfo = (mediaNode: BinaryNode): CatalogStatus => {
270
+ const node = getBinaryNodeChild(mediaNode, 'status_info')
271
+ return {
272
+ status: getBinaryNodeChildString(node, 'status')!,
273
+ canAppeal: getBinaryNodeChildString(node, 'can_appeal') === 'true',
274
+ }
275
+ }