ruby-baileys 0.0.0-stage → 1.5.17

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 (296) hide show
  1. package/EXPERIMENTAL.md +350 -0
  2. package/LICENSE +23 -0
  3. package/NOTICE.md +14 -0
  4. package/README.md +6265 -2
  5. package/WAProto/GenerateStatics.sh +3 -0
  6. package/WAProto/WAProto.proto +5479 -0
  7. package/WAProto/fix-imports.js +81 -0
  8. package/WAProto/index.d.ts +16877 -0
  9. package/WAProto/index.js +122159 -0
  10. package/assets/ruby_aspirant.jpg +0 -0
  11. package/assets/ruby_aspirant_4k.jpg +88 -0
  12. package/assets/ruby_aspirant_full.jpg +0 -0
  13. package/assets/ruby_aspirant_render.png +1 -0
  14. package/assets/ruby_aspirants_hd.jpg +0 -0
  15. package/assets/thumb.jpg +0 -0
  16. package/engine-requirements.js +14 -0
  17. package/index.cjs +29 -0
  18. package/index.d.ts +2 -0
  19. package/package.json +178 -4
  20. package/src/Defaults/index.d.ts +153 -0
  21. package/src/Defaults/index.js +165 -0
  22. package/src/MessageBuilder/bot-signature.d.ts +22 -0
  23. package/src/MessageBuilder/bot-signature.js +123 -0
  24. package/src/MessageBuilder/extras.d.ts +396 -0
  25. package/src/MessageBuilder/extras.js +1229 -0
  26. package/src/MessageBuilder/index.d.ts +210 -0
  27. package/src/MessageBuilder/index.js +3521 -0
  28. package/src/MessageBuilder/metaai.d.ts +438 -0
  29. package/src/MessageBuilder/metaai.js +891 -0
  30. package/src/Signal/Group/ciphertext-message.d.ts +10 -0
  31. package/src/Signal/Group/ciphertext-message.js +12 -0
  32. package/src/Signal/Group/group-session-builder.d.ts +8 -0
  33. package/src/Signal/Group/group-session-builder.js +28 -0
  34. package/src/Signal/Group/group_cipher.d.ts +11 -0
  35. package/src/Signal/Group/group_cipher.js +79 -0
  36. package/src/Signal/Group/index.d.ts +12 -0
  37. package/src/Signal/Group/index.js +12 -0
  38. package/src/Signal/Group/keyhelper.d.ts +7 -0
  39. package/src/Signal/Group/keyhelper.js +18 -0
  40. package/src/Signal/Group/sender-chain-key.d.ts +14 -0
  41. package/src/Signal/Group/sender-chain-key.js +26 -0
  42. package/src/Signal/Group/sender-key-distribution-message.d.ts +17 -0
  43. package/src/Signal/Group/sender-key-distribution-message.js +63 -0
  44. package/src/Signal/Group/sender-key-message.d.ts +19 -0
  45. package/src/Signal/Group/sender-key-message.js +66 -0
  46. package/src/Signal/Group/sender-key-name.d.ts +12 -0
  47. package/src/Signal/Group/sender-key-name.js +48 -0
  48. package/src/Signal/Group/sender-key-record.d.ts +13 -0
  49. package/src/Signal/Group/sender-key-record.js +41 -0
  50. package/src/Signal/Group/sender-key-state.d.ts +17 -0
  51. package/src/Signal/Group/sender-key-state.js +84 -0
  52. package/src/Signal/Group/sender-message-key.d.ts +12 -0
  53. package/src/Signal/Group/sender-message-key.js +26 -0
  54. package/src/Signal/libsignal.d.ts +55 -0
  55. package/src/Signal/libsignal.js +429 -0
  56. package/src/Signal/lid-mapping.d.ts +21 -0
  57. package/src/Signal/lid-mapping.js +275 -0
  58. package/src/Socket/Client/index.d.ts +3 -0
  59. package/src/Socket/Client/index.js +3 -0
  60. package/src/Socket/Client/types.d.ts +6 -0
  61. package/src/Socket/Client/types.js +10 -0
  62. package/src/Socket/Client/websocket.d.ts +13 -0
  63. package/src/Socket/Client/websocket.js +54 -0
  64. package/src/Socket/business.d.ts +432 -0
  65. package/src/Socket/business.js +380 -0
  66. package/src/Socket/chats.d.ts +248 -0
  67. package/src/Socket/chats.js +1485 -0
  68. package/src/Socket/communities.d.ts +599 -0
  69. package/src/Socket/communities.js +422 -0
  70. package/src/Socket/groups.d.ts +299 -0
  71. package/src/Socket/groups.js +340 -0
  72. package/src/Socket/index.d.ts +582 -0
  73. package/src/Socket/index.js +48 -0
  74. package/src/Socket/messages-recv.d.ts +371 -0
  75. package/src/Socket/messages-recv.js +1803 -0
  76. package/src/Socket/messages-send.d.ts +391 -0
  77. package/src/Socket/messages-send.js +1575 -0
  78. package/src/Socket/mex.d.ts +2 -0
  79. package/src/Socket/mex.js +45 -0
  80. package/src/Socket/newsletter.d.ts +469 -0
  81. package/src/Socket/newsletter.js +643 -0
  82. package/src/Socket/socket.d.ts +78 -0
  83. package/src/Socket/socket.js +1088 -0
  84. package/src/Store/index.d.ts +4 -0
  85. package/src/Store/index.js +4 -0
  86. package/src/Store/make-in-memory-store.d.ts +63 -0
  87. package/src/Store/make-in-memory-store.js +398 -0
  88. package/src/Store/make-ordered-dictionary.d.ts +13 -0
  89. package/src/Store/make-ordered-dictionary.js +79 -0
  90. package/src/Store/object-repository.d.ts +11 -0
  91. package/src/Store/object-repository.js +24 -0
  92. package/src/Types/Auth.d.ts +2 -0
  93. package/src/Types/Auth.js +2 -0
  94. package/src/Types/Bussines.d.ts +2 -0
  95. package/src/Types/Bussines.js +2 -0
  96. package/src/Types/Call.d.ts +2 -0
  97. package/src/Types/Call.js +2 -0
  98. package/src/Types/Chat.d.ts +3 -0
  99. package/src/Types/Chat.js +25 -0
  100. package/src/Types/Contact.d.ts +2 -0
  101. package/src/Types/Contact.js +2 -0
  102. package/src/Types/Events.d.ts +2 -0
  103. package/src/Types/Events.js +1 -0
  104. package/src/Types/GroupMetadata.d.ts +6 -0
  105. package/src/Types/GroupMetadata.js +7 -0
  106. package/src/Types/Label.d.ts +3 -0
  107. package/src/Types/Label.js +25 -0
  108. package/src/Types/LabelAssociation.d.ts +3 -0
  109. package/src/Types/LabelAssociation.js +7 -0
  110. package/src/Types/Message.d.ts +14 -0
  111. package/src/Types/Message.js +24 -0
  112. package/src/Types/Mex.d.ts +3 -0
  113. package/src/Types/Mex.js +96 -0
  114. package/src/Types/Product.d.ts +2 -0
  115. package/src/Types/Product.js +2 -0
  116. package/src/Types/Signal.d.ts +2 -0
  117. package/src/Types/Signal.js +1 -0
  118. package/src/Types/Socket.d.ts +2 -0
  119. package/src/Types/Socket.js +1 -0
  120. package/src/Types/State.d.ts +6 -0
  121. package/src/Types/State.js +55 -0
  122. package/src/Types/USync.d.ts +2 -0
  123. package/src/Types/USync.js +1 -0
  124. package/src/Types/index.d.ts +14 -0
  125. package/src/Types/index.js +26 -0
  126. package/src/Utils/auth-store.d.ts +30 -0
  127. package/src/Utils/auth-store.js +77 -0
  128. package/src/Utils/auth-utils.d.ts +59 -0
  129. package/src/Utils/auth-utils.js +274 -0
  130. package/src/Utils/browser-utils.d.ts +10 -0
  131. package/src/Utils/browser-utils.js +29 -0
  132. package/src/Utils/business.d.ts +50 -0
  133. package/src/Utils/business.js +227 -0
  134. package/src/Utils/chat-utils.d.ts +409 -0
  135. package/src/Utils/chat-utils.js +847 -0
  136. package/src/Utils/companion-reg-client-utils.d.ts +5 -0
  137. package/src/Utils/companion-reg-client-utils.js +40 -0
  138. package/src/Utils/crypto.d.ts +40 -0
  139. package/src/Utils/crypto.js +111 -0
  140. package/src/Utils/decode-wa-message.d.ts +100 -0
  141. package/src/Utils/decode-wa-message.js +374 -0
  142. package/src/Utils/event-buffer.d.ts +23 -0
  143. package/src/Utils/event-buffer.js +625 -0
  144. package/src/Utils/generics.d.ts +64 -0
  145. package/src/Utils/generics.js +376 -0
  146. package/src/Utils/group-metadata-cache.d.ts +5 -0
  147. package/src/Utils/group-metadata-cache.js +26 -0
  148. package/src/Utils/history.d.ts +76 -0
  149. package/src/Utils/history.js +132 -0
  150. package/src/Utils/html-app.d.ts +19 -0
  151. package/src/Utils/html-app.js +97 -0
  152. package/src/Utils/html-multiplayer.d.ts +10 -0
  153. package/src/Utils/html-multiplayer.js +95 -0
  154. package/src/Utils/identity-change-handler.d.ts +14 -0
  155. package/src/Utils/identity-change-handler.js +49 -0
  156. package/src/Utils/index.d.ts +45 -0
  157. package/src/Utils/index.js +45 -0
  158. package/src/Utils/link-preview-metadata.d.ts +47 -0
  159. package/src/Utils/link-preview-metadata.js +89 -0
  160. package/src/Utils/link-preview.d.ts +13 -0
  161. package/src/Utils/link-preview.js +80 -0
  162. package/src/Utils/logger.d.ts +3 -0
  163. package/src/Utils/logger.js +3 -0
  164. package/src/Utils/lt-hash.d.ts +7 -0
  165. package/src/Utils/lt-hash.js +4 -0
  166. package/src/Utils/make-mutex.d.ts +7 -0
  167. package/src/Utils/make-mutex.js +33 -0
  168. package/src/Utils/message-retry-manager.d.ts +80 -0
  169. package/src/Utils/message-retry-manager.js +256 -0
  170. package/src/Utils/messages-media.d.ts +137 -0
  171. package/src/Utils/messages-media.js +815 -0
  172. package/src/Utils/messages.d.ts +63 -0
  173. package/src/Utils/messages.js +2149 -0
  174. package/src/Utils/modern-messages.d.ts +150 -0
  175. package/src/Utils/modern-messages.js +496 -0
  176. package/src/Utils/native-flow.d.ts +11 -0
  177. package/src/Utils/native-flow.js +116 -0
  178. package/src/Utils/newsletter-status.d.ts +158 -0
  179. package/src/Utils/newsletter-status.js +651 -0
  180. package/src/Utils/noise-handler.d.ts +21 -0
  181. package/src/Utils/noise-handler.js +201 -0
  182. package/src/Utils/offline-node-processor.d.ts +10 -0
  183. package/src/Utils/offline-node-processor.js +34 -0
  184. package/src/Utils/optional-media.d.ts +3 -0
  185. package/src/Utils/optional-media.js +46 -0
  186. package/src/Utils/payment-messages.d.ts +66 -0
  187. package/src/Utils/payment-messages.js +161 -0
  188. package/src/Utils/pre-key-manager.d.ts +26 -0
  189. package/src/Utils/pre-key-manager.js +96 -0
  190. package/src/Utils/process-message.d.ts +61 -0
  191. package/src/Utils/process-message.js +689 -0
  192. package/src/Utils/reporting-utils.d.ts +13 -0
  193. package/src/Utils/reporting-utils.js +257 -0
  194. package/src/Utils/scheduled-message.d.ts +51 -0
  195. package/src/Utils/scheduled-message.js +113 -0
  196. package/src/Utils/sender-key-memory.d.ts +20 -0
  197. package/src/Utils/sender-key-memory.js +52 -0
  198. package/src/Utils/signal.d.ts +83 -0
  199. package/src/Utils/signal.js +194 -0
  200. package/src/Utils/stanza-ack.d.ts +17 -0
  201. package/src/Utils/stanza-ack.js +31 -0
  202. package/src/Utils/status-stickers.d.ts +127 -0
  203. package/src/Utils/status-stickers.js +261 -0
  204. package/src/Utils/sync-action-utils.d.ts +3 -0
  205. package/src/Utils/sync-action-utils.js +45 -0
  206. package/src/Utils/tc-token-utils.d.ts +30 -0
  207. package/src/Utils/tc-token-utils.js +156 -0
  208. package/src/Utils/ttl-cache.d.ts +29 -0
  209. package/src/Utils/ttl-cache.js +121 -0
  210. package/src/Utils/use-mongo-auth-state.d.ts +22 -0
  211. package/src/Utils/use-mongo-auth-state.js +68 -0
  212. package/src/Utils/use-multi-file-auth-state.d.ts +12 -0
  213. package/src/Utils/use-multi-file-auth-state.js +107 -0
  214. package/src/Utils/use-mysql-auth-state.d.ts +20 -0
  215. package/src/Utils/use-mysql-auth-state.js +80 -0
  216. package/src/Utils/use-postgres-auth-state.d.ts +20 -0
  217. package/src/Utils/use-postgres-auth-state.js +80 -0
  218. package/src/Utils/use-redis-auth-state.d.ts +20 -0
  219. package/src/Utils/use-redis-auth-state.js +90 -0
  220. package/src/Utils/use-single-file-auth-state.d.ts +11 -0
  221. package/src/Utils/use-single-file-auth-state.js +109 -0
  222. package/src/Utils/use-sqlite-auth-state.d.ts +13 -0
  223. package/src/Utils/use-sqlite-auth-state.js +121 -0
  224. package/src/Utils/useNekoDBAuth.d.ts +19 -0
  225. package/src/Utils/useNekoDBAuth.js +111 -0
  226. package/src/Utils/username.d.ts +12 -0
  227. package/src/Utils/username.js +59 -0
  228. package/src/Utils/validate-connection.d.ts +44 -0
  229. package/src/Utils/validate-connection.js +208 -0
  230. package/src/Utils/voice-recognition.d.ts +53 -0
  231. package/src/Utils/voice-recognition.js +219 -0
  232. package/src/Voip/audio-feeder.d.ts +25 -0
  233. package/src/Voip/audio-feeder.js +269 -0
  234. package/src/Voip/index.d.ts +89 -0
  235. package/src/Voip/index.js +937 -0
  236. package/src/Voip/relay-transport.d.ts +6 -0
  237. package/src/Voip/relay-transport.js +825 -0
  238. package/src/Voip/signaling.d.ts +12 -0
  239. package/src/Voip/signaling.js +1100 -0
  240. package/src/Voip/types.d.ts +3 -0
  241. package/src/Voip/types.js +13 -0
  242. package/src/Voip/video-feeder.d.ts +25 -0
  243. package/src/Voip/video-feeder.js +269 -0
  244. package/src/Voip/wasm-engine.d.ts +27 -0
  245. package/src/Voip/wasm-engine.js +1308 -0
  246. package/src/Voip/worker-bootstrap.js +1024 -0
  247. package/src/WABinary/constants.d.ts +23 -0
  248. package/src/WABinary/constants.js +1301 -0
  249. package/src/WABinary/decode.d.ts +10 -0
  250. package/src/WABinary/decode.js +262 -0
  251. package/src/WABinary/encode.d.ts +3 -0
  252. package/src/WABinary/encode.js +220 -0
  253. package/src/WABinary/generic-utils.d.ts +77 -0
  254. package/src/WABinary/generic-utils.js +214 -0
  255. package/src/WABinary/index.d.ts +6 -0
  256. package/src/WABinary/index.js +6 -0
  257. package/src/WABinary/jid-utils.d.ts +31 -0
  258. package/src/WABinary/jid-utils.js +98 -0
  259. package/src/WABinary/types.d.ts +2 -0
  260. package/src/WABinary/types.js +1 -0
  261. package/src/WAM/BinaryInfo.d.ts +8 -0
  262. package/src/WAM/BinaryInfo.js +10 -0
  263. package/src/WAM/constants.d.ts +34927 -0
  264. package/src/WAM/constants.js +22853 -0
  265. package/src/WAM/encode.d.ts +2 -0
  266. package/src/WAM/encode.js +149 -0
  267. package/src/WAM/index.d.ts +4 -0
  268. package/src/WAM/index.js +4 -0
  269. package/src/WAUSync/Protocols/USyncContactProtocol.d.ts +37 -0
  270. package/src/WAUSync/Protocols/USyncContactProtocol.js +51 -0
  271. package/src/WAUSync/Protocols/USyncDeviceProtocol.d.ts +23 -0
  272. package/src/WAUSync/Protocols/USyncDeviceProtocol.js +52 -0
  273. package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +13 -0
  274. package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
  275. package/src/WAUSync/Protocols/USyncStatusProtocol.d.ts +13 -0
  276. package/src/WAUSync/Protocols/USyncStatusProtocol.js +38 -0
  277. package/src/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
  278. package/src/WAUSync/Protocols/USyncUsernameProtocol.js +24 -0
  279. package/src/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +39 -0
  280. package/src/WAUSync/Protocols/UsyncBotProfileProtocol.js +50 -0
  281. package/src/WAUSync/Protocols/UsyncLIDProtocol.d.ts +15 -0
  282. package/src/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
  283. package/src/WAUSync/Protocols/index.d.ts +6 -0
  284. package/src/WAUSync/Protocols/index.js +6 -0
  285. package/src/WAUSync/USyncQuery.d.ts +21 -0
  286. package/src/WAUSync/USyncQuery.js +94 -0
  287. package/src/WAUSync/USyncUser.d.ts +17 -0
  288. package/src/WAUSync/USyncUser.js +31 -0
  289. package/src/WAUSync/index.d.ts +4 -0
  290. package/src/WAUSync/index.js +4 -0
  291. package/src/assets/wasm/README.md +76 -0
  292. package/src/assets/wasm/loader.js +5 -0
  293. package/src/assets/wasm/whatsapp.wasm +0 -0
  294. package/src/assets/wasm/worker-modules.js +273 -0
  295. package/src/index.d.ts +49 -0
  296. package/src/index.js +54 -0
@@ -0,0 +1,891 @@
1
+ /* Elaina Baileys maintained distribution. Upstream notices and license are preserved in LICENSE and NOTICE.md. */
2
+ import { AIRich } from './index.js'
3
+ import { AddonActionType } from './extras.js'
4
+ import { generateWAMessageFromContent } from '../Utils/messages.js'
5
+ import { BOT_SIGNATURE_USE_CASE_WA_BOT_MSG, verifyBotSignature } from './bot-signature.js'
6
+
7
+ export const MapQueryStatus = Object.freeze({ FETCHING: 'FETCHING', FETCHED: 'FETCHED', FAILED: 'FAILED' })
8
+ export const MapItemMarkerType = Object.freeze({ PIN: 'PIN', RADIUS: 'RADIUS' })
9
+ export const PlaceDetailsItemType = Object.freeze({ PLACE: 'PLACE', MARKETPLACE_LISTING: 'MARKETPLACE_LISTING' })
10
+ export const PlaceOpeningStatus = Object.freeze({ OPEN: 'OPEN', CLOSED: 'CLOSED' })
11
+ export const PlacePriceLevel = Object.freeze({ CHEAP: 'CHEAP', MODERATE: 'MODERATE', EXPENSIVE: 'EXPENSIVE', SPLURGE: 'SPLURGE' })
12
+
13
+ export const ClippyArtifactType = Object.freeze({ MINI_APP: 'MINI_APP', STATIC_HTML: 'STATIC_HTML' })
14
+
15
+ export const SportsLeague = Object.freeze({ NFL: 'NFL', EURO: 'EURO', WORLD_CUP: 'WORLD_CUP' })
16
+ export const SportsGameStatus = Object.freeze({ SCHEDULED: 'SCHEDULED', LIVE: 'LIVE', FINAL: 'FINAL' })
17
+ export const SportsSeasonType = Object.freeze({ PRESEASON: 'PRESEASON', REGULAR: 'REGULAR', POSTSEASON: 'POSTSEASON' })
18
+
19
+ export const CompactEntityType = Object.freeze({
20
+ PERSON: 'PERSON',
21
+ PAGE: 'PAGE',
22
+ GROUP: 'GROUP',
23
+ INSTAGRAM_ACCOUNT: 'INSTAGRAM_ACCOUNT',
24
+ CALENDAR_EVENT: 'CALENDAR_EVENT'
25
+ })
26
+ export const CompactEntityActionType = Object.freeze({
27
+ FOLLOW: 'FOLLOW',
28
+ UNFOLLOW: 'UNFOLLOW',
29
+ JOIN: 'JOIN',
30
+ LEAVE: 'LEAVE',
31
+ MESSAGE: 'MESSAGE',
32
+ VIEW_DETAILS: 'VIEW_DETAILS'
33
+ })
34
+
35
+ export const ActionListRowType = Object.freeze({ ACTION: 'ACTION', NAVIGATION: 'NAVIGATION' })
36
+
37
+ export const SocialEntityItemType = Object.freeze({
38
+ FB_PROFILE: 'FB_PROFILE',
39
+ FB_PAGE: 'FB_PAGE',
40
+ FB_GROUP: 'FB_GROUP',
41
+ IG_PROFILE: 'IG_PROFILE',
42
+ THREADS_PROFILE: 'THREADS_PROFILE'
43
+ })
44
+
45
+ export const SourceApp = Object.freeze({ FACEBOOK: 'FACEBOOK', INSTAGRAM: 'INSTAGRAM', THREADS: 'THREADS' })
46
+ export const PostType = Object.freeze({ PAGE_POST: 'PAGE_POST', GROUP_POST: 'GROUP_POST' })
47
+ export const PostOrientation = Object.freeze({ PORTRAIT: 'PORTRAIT', LANDSCAPE: 'LANDSCAPE' })
48
+ export const ProductSourceType = Object.freeze({ CATALOG: 'CATALOG', MARKETPLACE: 'MARKETPLACE' })
49
+
50
+ export const SearchPlannerStepStatus = Object.freeze({
51
+ PLANNED: 'PLANNED',
52
+ IN_PROGRESS: 'IN_PROGRESS',
53
+ COMPLETED: 'COMPLETED',
54
+ STOPPED: 'STOPPED'
55
+ })
56
+ export const OrchestratorSearchEngine = Object.freeze({
57
+ BING: 'BING',
58
+ BRAVE: 'BRAVE',
59
+ GOOGLE: 'GOOGLE',
60
+ HELP_CENTER: 'HELP_CENTER',
61
+ IN_HOUSE: 'IN_HOUSE',
62
+ KSS: 'KSS',
63
+ MASE: 'MASE'
64
+ })
65
+
66
+ export const ProfessionalConsentStatus = Object.freeze({ ALLOWED: 'ALLOWED', NEEDS_CONSENT: 'NEEDS_CONSENT' })
67
+
68
+ export const AccountLinkingIntegration = Object.freeze({
69
+ APPLE_HEALTH: 'APPLE_HEALTH',
70
+ GMAIL: 'GMAIL',
71
+ GOOGLE_CALENDAR: 'GOOGLE_CALENDAR',
72
+ GOOGLE_CONTACTS: 'GOOGLE_CONTACTS',
73
+ GOOGLE_DRIVE: 'GOOGLE_DRIVE',
74
+ GOOGLE_HEALTH_CONNECT: 'GOOGLE_HEALTH_CONNECT',
75
+ OUTLOOK_CALENDAR: 'OUTLOOK_CALENDAR',
76
+ OUTLOOK_CONTACTS: 'OUTLOOK_CONTACTS',
77
+ OUTLOOK_MAIL: 'OUTLOOK_MAIL'
78
+ })
79
+ export const AccountLinkingStatus = Object.freeze({ INITIATED: 'INITIATED', LINKED: 'LINKED', UNLINKED: 'UNLINKED' })
80
+
81
+ export const CalendarEventOperation = Object.freeze({ CREATE: 'CREATE', UPDATE: 'UPDATE', DELETE: 'DELETE' })
82
+ export const CalendarEventState = Object.freeze({ PENDING: 'PENDING', CONFIRMED: 'CONFIRMED', CANCELLED: 'CANCELLED' })
83
+ export const WidgetCtaKind = Object.freeze({ CONFIRM: 'CONFIRM', CANCEL: 'CANCEL', OTHER: 'OTHER' })
84
+ export const WidgetCtaState = Object.freeze({ PENDING: 'PENDING', CONFIRMED: 'CONFIRMED', CANCELLED: 'CANCELLED' })
85
+
86
+ export const MultipleResponseLayoutType = Object.freeze({ IN_THREAD: 'IN_THREAD', BOTTOM_SHEET: 'BOTTOM_SHEET' })
87
+
88
+ export const ThreadSurfingEntityType = Object.freeze({
89
+ CELEBRITY: 'CELEBRITY',
90
+ INFO_TERM: 'INFO_TERM',
91
+ MOVIE: 'MOVIE',
92
+ RESTAURANT: 'RESTAURANT',
93
+ SPORTS_TEAM: 'SPORTS_TEAM',
94
+ TV_SHOWS: 'TV_SHOWS'
95
+ })
96
+ export const ThreadSurfingActionType = Object.freeze({ AI_LOOKUP: 'AI_LOOKUP', CONTEXTUAL_MENU: 'CONTEXTUAL_MENU' })
97
+
98
+ export const MediaShape = Object.freeze({ CIRCLE: 'CIRCLE', SQUARE: 'SQUARE', VERTICAL: 'VERTICAL' })
99
+ export const MediaHorizontalAlignment = Object.freeze({ START: 'START', END: 'END' })
100
+ export const MediaVerticalAlignment = Object.freeze({ TOP: 'TOP', CENTER: 'CENTER' })
101
+ export const AddonActionAlignment = Object.freeze({ START: 'START', END: 'END' })
102
+ export const ImageAssetQueryStatus = Object.freeze({ FETCHING: 'FETCHING', FETCHED: 'FETCHED', FAILED: 'FAILED' })
103
+
104
+ export const CodeBlockType = Object.freeze({
105
+ DEFAULT: 'DEFAULT',
106
+ COMMENT: 'COMMENT',
107
+ KEYWORD: 'KEYWORD',
108
+ METHOD: 'METHOD',
109
+ NUMBER: 'NUMBER',
110
+ STR: 'STR'
111
+ })
112
+
113
+ export const FollowUpSuggestionCategory = Object.freeze({
114
+ ADD: 'ADD',
115
+ ANIMATE: 'ANIMATE',
116
+ FRAME: 'FRAME',
117
+ LIGHT: 'LIGHT',
118
+ OTHER: 'OTHER',
119
+ RETOUCH: 'RETOUCH',
120
+ SCENE: 'SCENE',
121
+ STYLE: 'STYLE'
122
+ })
123
+
124
+ export const InformTreatmentRenderingType = Object.freeze({
125
+ GEOBLOCK: 'GEOBLOCK',
126
+ MEDIA_LABEL: 'MEDIA_LABEL',
127
+ POST_COVER: 'POST_COVER',
128
+ POST_LABEL: 'POST_LABEL',
129
+ WARNING_SCREENS: 'WARNING_SCREENS'
130
+ })
131
+
132
+ export const UnifiedResponseSectionType = Object.freeze({ REASONING: 'REASONING', RESPONDING: 'RESPONDING' })
133
+ export const UnifiedResponseMessageGroupKind = Object.freeze({ COMMENTARY: 'COMMENTARY', PRIMARY_RESPONSE: 'PRIMARY_RESPONSE' })
134
+
135
+ const trimEmpty = (object) => {
136
+ for (const key of Object.keys(object)) {
137
+ if (object[key] === undefined) {
138
+ delete object[key]
139
+ }
140
+ }
141
+ return object
142
+ }
143
+
144
+ const typed = (typename, fields) => trimEmpty({ ...fields, __typename: typename })
145
+
146
+ const layoutSection = (name, data, viewModelFields = {}) => {
147
+ const section = AIRich.newLayout(name, data)
148
+ Object.assign(section.view_model, trimEmpty({ ...viewModelFields }))
149
+ return section
150
+ }
151
+
152
+ const url = (value, fallback) => (value === undefined ? undefined : { url: value, url_fallback: fallback ?? value })
153
+
154
+ export const customSection = (typename, fields = {}, { layout = 'Single' } = {}) => {
155
+ if (typeof typename !== 'string' || !typename) {
156
+ throw new TypeError('customSection needs a __typename, that is the only thing the client dispatches on')
157
+ }
158
+ return AIRich.newLayout(layout, typed(typename, fields))
159
+ }
160
+
161
+ export const placeItem = ({
162
+ id,
163
+ name,
164
+ description,
165
+ imageUrl,
166
+ itemType = PlaceDetailsItemType.PLACE,
167
+ categoryId,
168
+ categoryName,
169
+ priceLevel,
170
+ openingStatus,
171
+ openingHours,
172
+ rating,
173
+ latitude,
174
+ longitude,
175
+ streetAddress,
176
+ street,
177
+ locality,
178
+ region,
179
+ country,
180
+ postalCode,
181
+ timezone,
182
+ marketplace
183
+ } = {}) => typed('GenAIPlaceDetailsItem', {
184
+ id: id === undefined ? undefined : String(id),
185
+ name,
186
+ description,
187
+ image_url: imageUrl,
188
+ item_type: itemType,
189
+ category: categoryId === undefined && categoryName === undefined
190
+ ? undefined
191
+ : typed('GenAIPlaceDetailsItemCategory', { category_id: categoryId, display_name: categoryName }),
192
+ price_level: priceLevel,
193
+ opening_status: openingStatus,
194
+ opening_hours: openingHours?.map(hours => typed('GenAIPlaceDetailsItemOpeningHours', {
195
+ day: hours.day,
196
+ time: hours.time,
197
+ open: hours.open === undefined ? undefined : typed('GenAIPlaceDetailsItemOpeningHoursTime', { time: hours.open }),
198
+ close: hours.close === undefined ? undefined : typed('GenAIPlaceDetailsItemOpeningHoursTime', { time: hours.close })
199
+ })),
200
+ rating: rating === undefined ? undefined : typed('GenAIPlaceDetailsItemRating', { avg_rating: Number(rating) }),
201
+ address: trimEmpty({
202
+ latitude,
203
+ longitude,
204
+ street_address: streetAddress,
205
+ street,
206
+ locality,
207
+ region,
208
+ country,
209
+ postal_code: postalCode,
210
+ timezone
211
+ }),
212
+ marketplace_metadata: marketplace === undefined
213
+ ? undefined
214
+ : typed('GenAIMarketplaceMetadata', {
215
+ price: marketplace.price,
216
+ sale_price: marketplace.salePrice,
217
+ is_unavailable: marketplace.unavailable
218
+ })
219
+ })
220
+
221
+ export const mapSection = ({ items = [], motivation, staticMapUrl, staticMapDarkUrl, queryStatus = MapQueryStatus.FETCHED } = {}) =>
222
+ AIRich.newLayout('Single', typed('GenAIMapPrimitive', {
223
+ map_query_status: queryStatus,
224
+ static_map: staticMapUrl === undefined
225
+ ? undefined
226
+ : typed('GenAIMapItemStaticMap', { default_url: staticMapUrl, dark_theme_url: staticMapDarkUrl ?? staticMapUrl }),
227
+ items,
228
+ motivation
229
+ }))
230
+
231
+ export const locationPermissionSection = (placeholder = '') =>
232
+ AIRich.newLayout('Single', typed('GenAILocationPermissionPrimitive', { placeholder }))
233
+
234
+ export const timestampPlaceholderSection = (placeholder = '') =>
235
+ AIRich.newLayout('Single', typed('GenAITimestampPlaceholderPrimitive', { placeholder }))
236
+
237
+ const sportsTeam = (team = {}) => typed('GenAISportsTeam', {
238
+ name: team.name,
239
+ abbreviation: team.abbreviation,
240
+ country_code: team.countryCode,
241
+ icon: team.icon === undefined ? undefined : typed('GenAISportsTeamIcon', { image: url(team.icon, team.iconFallback) })
242
+ })
243
+
244
+ const sportsRecord = (record) => (record === undefined
245
+ ? undefined
246
+ : typed('GenAISportsTeamRecord', { wins: record.wins, losses: record.losses, ties: record.ties }))
247
+
248
+ export const sportsSection = ({
249
+ gameId,
250
+ league = SportsLeague.NFL,
251
+ status = SportsGameStatus.SCHEDULED,
252
+ statusDetail,
253
+ startTime,
254
+ venue,
255
+ group,
256
+ groupName,
257
+ homeTeam,
258
+ awayTeam,
259
+ homeScore,
260
+ awayScore,
261
+ homeRecord,
262
+ awayRecord,
263
+ seasonType,
264
+ week,
265
+ contentTypename = 'GenAIAmericanFootballGameContent'
266
+ } = {}) => {
267
+ if (!gameId) {
268
+ throw new TypeError('sportsSection requires gameId, the widget is keyed on it')
269
+ }
270
+ return AIRich.newLayout('Single', typed('GenAISportsWidgetPrimitive', {
271
+ game_id: String(gameId),
272
+ league,
273
+ status,
274
+ status_detail: statusDetail,
275
+ start_time_utc_seconds: startTime === undefined ? undefined : Number(startTime),
276
+ venue: venue === undefined
277
+ ? undefined
278
+ : typed('GenAISportsVenue', { name: venue.name, city: venue.city, state: venue.state, country: venue.country }),
279
+ group: group === undefined && groupName === undefined
280
+ ? undefined
281
+ : typed('GenAISportsGroup', { group_name: groupName ?? group }),
282
+ content: typed(contentTypename, {
283
+ home_team: homeTeam === undefined ? undefined : sportsTeam(homeTeam),
284
+ away_team: awayTeam === undefined ? undefined : sportsTeam(awayTeam),
285
+ home_score: homeScore,
286
+ away_score: awayScore,
287
+ home_record: sportsRecord(homeRecord),
288
+ away_record: sportsRecord(awayRecord),
289
+ season_type: seasonType,
290
+ week
291
+ })
292
+ }))
293
+ }
294
+
295
+ export const videoSection = ({
296
+ postId,
297
+ title,
298
+ url: reelsUrl,
299
+ thumbnailUrl,
300
+ creator,
301
+ avatarUrl,
302
+ contentHash,
303
+ likes,
304
+ comments,
305
+ shares,
306
+ isVerified,
307
+ sourceApp,
308
+ progressiveUrls = [],
309
+ dashManifests = []
310
+ } = {}) => AIRich.newLayout('Single', typed('GenAIVideoPrimitive', {
311
+ post_id: postId === undefined ? undefined : String(postId),
312
+ reels_title: title,
313
+ reels_url: reelsUrl,
314
+ thumbnail_url: thumbnailUrl,
315
+ creator,
316
+ avatar_url: avatarUrl,
317
+ content_hash: contentHash,
318
+ likes_count: likes,
319
+ comments_count: comments,
320
+ shares_count: shares,
321
+ is_verified: isVerified,
322
+ source_app: sourceApp,
323
+ video_delivery_response: typed('GenAIVideoDeliveryResponse', {
324
+ progressive_urls: progressiveUrls.map(value => typed('GenAIProgressiveUrlResponse', { progressive_url: value })),
325
+ dash_manifests: dashManifests.map(value => typed('GenAIDashManifestResponse', { manifest_xml: value }))
326
+ })
327
+ }))
328
+
329
+ export const reminderSection = ({
330
+ reminderId,
331
+ title,
332
+ triggerType,
333
+ triggerTime,
334
+ createTime,
335
+ isDeleted,
336
+ thumbnailUrl,
337
+ fullSizeUrl,
338
+ mediaKey
339
+ } = {}) => {
340
+ if (!reminderId) {
341
+ throw new TypeError('reminderSection requires reminderId')
342
+ }
343
+ return AIRich.newLayout('Single', typed('GenAIReminderPrimitive', {
344
+ reminder_id: String(reminderId),
345
+ title,
346
+ trigger_type: triggerType,
347
+ trigger_time: triggerTime,
348
+ create_time: createTime,
349
+ is_deleted: isDeleted,
350
+ thumbnail_url: thumbnailUrl,
351
+ full_size_url: fullSizeUrl,
352
+ reminder_media_key: mediaKey
353
+ }))
354
+ }
355
+
356
+ export const commentSection = ({
357
+ text,
358
+ url: commentUrl,
359
+ actorName,
360
+ profileImage,
361
+ subtitle,
362
+ likes,
363
+ replies,
364
+ isVerified
365
+ } = {}) => AIRich.newLayout('Single', typed('GenAICommentPrimitive', {
366
+ comment_text: text,
367
+ comment_url: commentUrl,
368
+ actor_name: actorName,
369
+ profile_image: profileImage,
370
+ subtitle,
371
+ likes_count: likes,
372
+ replies_count: replies,
373
+ is_verified: isVerified
374
+ }))
375
+
376
+ export const compactEntitySection = ({
377
+ title,
378
+ subtitle,
379
+ secondarySubtitle,
380
+ image,
381
+ entityId,
382
+ entityUrl,
383
+ entityType = CompactEntityType.PERSON,
384
+ actionType,
385
+ isVerified
386
+ } = {}) => AIRich.newLayout('Single', typed('GenAICompactEntityPrimitive', {
387
+ title,
388
+ subtitle,
389
+ secondary_subtitle: secondarySubtitle,
390
+ image,
391
+ entity_id: entityId === undefined ? undefined : String(entityId),
392
+ entity_url: entityUrl,
393
+ entity_type: entityType,
394
+ action_type: actionType,
395
+ is_verified: isVerified
396
+ }))
397
+
398
+ export const actionListRow = ({ title, subtitle, action, icon, url: rowUrl, rowType = ActionListRowType.ACTION } = {}) =>
399
+ typed('GenAIActionListRow', {
400
+ title,
401
+ subtitle,
402
+ action,
403
+ icon,
404
+ url: rowUrl,
405
+ row_type: rowType
406
+ })
407
+
408
+ export const actionListSection = (rows = []) =>
409
+ AIRich.newLayout('Single', typed('GenAIActionListPrimitive', { rows }))
410
+
411
+ const plannerFields = ({ sources = [], steps = [], queryUrl, queryFavicon, searchEngine, facepileFavicons = [], responseId } = {}) => ({
412
+ response_id: responseId,
413
+ sources,
414
+ steps,
415
+ query_url: queryUrl,
416
+ query_favicon: queryFavicon,
417
+ search_engine: searchEngine,
418
+ facepile_favicons: facepileFavicons
419
+ })
420
+
421
+ export const plannerStep = ({ title, instruction, status = SearchPlannerStepStatus.PLANNED } = {}) =>
422
+ typed('GenAISearchPlannerStep', {
423
+ title,
424
+ status,
425
+ instruction: instruction === undefined
426
+ ? undefined
427
+ : typed('GenAISearchPlannerInstruction', { text: instruction })
428
+ })
429
+
430
+ export const searchPlannerSection = (options = {}) =>
431
+ AIRich.newLayout('Single', typed('GenAISearchPlannerStepsPrimitive', plannerFields(options)))
432
+
433
+ export const searchResultV2Section = (options = {}) =>
434
+ AIRich.newLayout('Single', typed('GenAISearchResultV2Primitive', plannerFields(options)))
435
+
436
+ export const plannerSnippetSection = ({ header, currentStep, totalSteps, status = SearchPlannerStepStatus.IN_PROGRESS } = {}) =>
437
+ AIRich.newLayout('Single', typed('GenAISearchPlannerStepSnippetPrimitive', {
438
+ header,
439
+ current_step: currentStep,
440
+ total_steps: totalSteps,
441
+ status
442
+ }))
443
+
444
+ export const chainOfThoughtSection = ({ header, subtitle, plannerState, imageArtifacts, text } = {}) =>
445
+ AIRich.newLayout('Single', typed('GenAIChainOfThoughtStepPrimitive', {
446
+ header,
447
+ subtitle,
448
+ planner_state: plannerState,
449
+ image_artifacts: imageArtifacts,
450
+ markdown_text: text === undefined ? undefined : typed('GenAIChainOfThoughtStepMarkdownText', { text })
451
+ }))
452
+
453
+ export const searchAdSection = ({ storyId, actorName, actorImageUrl, imageUrl, message } = {}) =>
454
+ AIRich.newLayout('Single', typed('GenAISearchAdPrimitive', {
455
+ story_id: storyId === undefined ? undefined : String(storyId),
456
+ actor_name: actorName,
457
+ actor_image_url: actorImageUrl,
458
+ image_url: imageUrl,
459
+ message
460
+ }))
461
+
462
+ export const transparencySignal = ({ id, signalType, value, memory } = {}) =>
463
+ typed('GenAIP13nUiSignalValue', {
464
+ id: id === undefined ? undefined : String(id),
465
+ signal_type: signalType,
466
+ value,
467
+ memory
468
+ })
469
+
470
+ export const transparencySection = ({ annotation, signals = [], responseId } = {}) =>
471
+ AIRich.newLayout('Single', typed('GenAIP13NTransparencyPrimitive', {
472
+ annotation,
473
+ signals: typed('GenAIP13nUiSignals', { signals }),
474
+ response_id: responseId
475
+ }))
476
+
477
+ export const professionalConsentSection = ({
478
+ title,
479
+ body,
480
+ status = ProfessionalConsentStatus.NEEDS_CONSENT,
481
+ providerLabel,
482
+ providerIconUrl,
483
+ ctaLabel,
484
+ allowedLabel,
485
+ allowedCtaLabel,
486
+ allowedProviderLabel,
487
+ allowedDescription,
488
+ description,
489
+ primaryLabel,
490
+ secondaryLabel,
491
+ subtitle,
492
+ originalPrompt,
493
+ learnMoreLabel,
494
+ learnMoreUrl
495
+ } = {}) => AIRich.newLayout('Single', typed('GenAIProfessionalConsentPrimitive', {
496
+ title,
497
+ body,
498
+ subtitle,
499
+ description,
500
+ status,
501
+ provider_label: providerLabel,
502
+ provider_icon_url: providerIconUrl,
503
+ cta_label: ctaLabel,
504
+ allowed_label: allowedLabel,
505
+ allowed_cta_label: allowedCtaLabel,
506
+ allowed_provider_label: allowedProviderLabel,
507
+ allowed_description: allowedDescription,
508
+ primary_label: primaryLabel,
509
+ secondary_label: secondaryLabel,
510
+ original_prompt: originalPrompt,
511
+ learn_more_label: learnMoreLabel,
512
+ learn_more_url: learnMoreUrl
513
+ }))
514
+
515
+ export const accountLinkingApp = ({ label, integrationFbid, integrationSlug, iconUrl } = {}) =>
516
+ typed('GenAI3PAccountLinkingBottomsheetAppItem', {
517
+ label,
518
+ integration_fbid: integrationFbid === undefined ? undefined : String(integrationFbid),
519
+ integration_slug: integrationSlug,
520
+ icon_url: iconUrl
521
+ })
522
+
523
+ export const accountLinkingSection = ({
524
+ title,
525
+ subtitle,
526
+ imageUrl,
527
+ ctaLabel,
528
+ ctaUrl,
529
+ originalPrompt,
530
+ integrationType = AccountLinkingIntegration.GOOGLE_CALENDAR,
531
+ integrationStatus = AccountLinkingStatus.UNLINKED,
532
+ integrationId,
533
+ apps
534
+ } = {}) => AIRich.newLayout('Single', typed('GenAI3PAccountLinkingUpsellPrimitive', {
535
+ title,
536
+ subtitle,
537
+ image_url: imageUrl,
538
+ cta_label: ctaLabel,
539
+ cta_url: ctaUrl,
540
+ original_prompt: originalPrompt,
541
+ integration_type: integrationType,
542
+ integration_status: integrationStatus,
543
+ integration_id: integrationId === undefined ? undefined : String(integrationId),
544
+ bottomsheet: apps === undefined ? undefined : typed('GenAI3PAccountLinkingBottomsheet', { apps })
545
+ }))
546
+
547
+ export const calendarEvent = ({
548
+ title,
549
+ startTime,
550
+ endTime,
551
+ location,
552
+ description,
553
+ recurrenceText,
554
+ deeplink,
555
+ attendees = []
556
+ } = {}) => typed('GenAI3PExtCalendarEventItem', {
557
+ title,
558
+ start_time: startTime,
559
+ end_time: endTime,
560
+ location,
561
+ description,
562
+ recurrence_text: recurrenceText,
563
+ deeplink,
564
+ attendees: attendees.map(attendee => typed('GenAI3PExtCalendarAttendee', {
565
+ email: attendee.email,
566
+ display_name: attendee.displayName ?? attendee.name
567
+ }))
568
+ })
569
+
570
+ export const calendarWidgetSection = ({ title, iconUrls = [], sections = [], ctas = [], toast } = {}) =>
571
+ AIRich.newLayout('Single', typed('GenAI3PExtWidgetPrimitive', {
572
+ header: typed('GenAI3PExtWidgetStandardHeader', { title, leading_items: iconUrls }),
573
+ sections: sections.map(section => typed('GenAI3PExtCalendarDateSection', {
574
+ date: section.date,
575
+ events: typed('GenAI3PExtCalendarEventList', { events: section.events ?? [] })
576
+ })),
577
+ ctas: ctas.map(cta => typed('GenAI3PExtWidgetCTA', {
578
+ label: cta.label,
579
+ kind: cta.kind ?? WidgetCtaKind.CONFIRM,
580
+ state: cta.state ?? WidgetCtaState.PENDING,
581
+ tool_call_id: cta.toolCallId,
582
+ tool_name: cta.toolName,
583
+ analytics_action: cta.analyticsAction
584
+ })),
585
+ toast: toast === undefined ? undefined : typed('GenAI3PExtWidgetToast', { label: toast })
586
+ }))
587
+
588
+ export const chainingSuggestionSection = ({ promptText, title, imageUri, externalConversationId, topic, cardId } = {}) =>
589
+ AIRich.newLayout('Single', typed('GenAIChainingSuggestionPrimitive', {
590
+ prompt_text: promptText,
591
+ title,
592
+ image_uri: imageUri,
593
+ external_conversation_id: externalConversationId,
594
+ topic,
595
+ card_id: cardId
596
+ }))
597
+
598
+ export const mediaItem = ({
599
+ previewUrl,
600
+ fullUrl,
601
+ darkPreviewUrl,
602
+ darkFullUrl,
603
+ source,
604
+ contentHash,
605
+ assetQueryStatus = ImageAssetQueryStatus.FETCHED,
606
+ followUpPills = []
607
+ } = {}) => typed('GenAIMediaItem', {
608
+ preview_image: url(previewUrl),
609
+ full_image: url(fullUrl),
610
+ dark_mode_preview_image: url(darkPreviewUrl),
611
+ dark_mode_full_image: url(darkFullUrl),
612
+ source,
613
+ content_hash: contentHash,
614
+ asset_query_status: assetQueryStatus,
615
+ follow_up_pills: followUpPills.map(pill => typed('GenAIFollowUpSuggestionPillPrimitive', {
616
+ prompt_text: typeof pill === 'string' ? pill : pill.promptText,
617
+ category: typeof pill === 'string' ? FollowUpSuggestionCategory.OTHER : pill.category ?? FollowUpSuggestionCategory.OTHER
618
+ }))
619
+ })
620
+
621
+ export const mediaGridSection = (items = []) => AIRich.newLayout('Grid', items)
622
+
623
+ export const contextualSourcesSection = (sources = []) =>
624
+ AIRich.newLayout('Single', typed('GenAIContextualSourcesViewModel', {
625
+ contextual_sources: sources.map(source => trimEmpty({
626
+ uri: source.uri ?? source.url,
627
+ display_name: source.displayName ?? source.title,
628
+ favicon_uri: source.favicon
629
+ }))
630
+ }))
631
+
632
+ export const threadSurfingItem = ({ entity, entityType = ThreadSurfingEntityType.INFO_TERM, prompts = [] } = {}) =>
633
+ typed('GenAIThreadSurfingItem', {
634
+ entity,
635
+ entity_type: entityType,
636
+ prompts: prompts.map((prompt, index) => typed('GenAIThreadSurfingPrompt', {
637
+ prompt: typeof prompt === 'string' ? prompt : prompt.prompt,
638
+ prompt_id: typeof prompt === 'string' ? String(index) : String(prompt.promptId ?? index)
639
+ }))
640
+ })
641
+
642
+ export const socialEntityItem = ({ entityId, name, fullName, pictureUrl, entityUrl, entityType, isVerified } = {}) =>
643
+ typed('GenAISocialEntityItem', {
644
+ entity_id: entityId === undefined ? undefined : String(entityId),
645
+ entity_name: name,
646
+ entity_full_name: fullName,
647
+ entity_picture_url: pictureUrl,
648
+ entity_url: entityUrl,
649
+ entity_type: entityType,
650
+ is_verified: isVerified
651
+ })
652
+
653
+ export const placeEntityItem = ({ placeId, name, imageUrl, motivation } = {}) =>
654
+ typed('GenAIPlaceEntityItem', {
655
+ place_id: placeId === undefined ? undefined : String(placeId),
656
+ name,
657
+ image_url: imageUrl,
658
+ motivation
659
+ })
660
+
661
+ export const productEntityItem = ({
662
+ productId,
663
+ title,
664
+ productUrl,
665
+ imageUrl,
666
+ additionalImages = [],
667
+ price,
668
+ salePrice,
669
+ brand,
670
+ sourceType = ProductSourceType.CATALOG,
671
+ isUnavailable,
672
+ adTrackingCode
673
+ } = {}) => typed('GenAIProductEntityItem', {
674
+ product_id: productId === undefined ? undefined : String(productId),
675
+ title,
676
+ product_url: productUrl,
677
+ image: url(imageUrl),
678
+ additional_images: additionalImages.map(value => url(value)),
679
+ price,
680
+ sale_price: salePrice,
681
+ brand,
682
+ source_type: sourceType,
683
+ is_unavailable: isUnavailable,
684
+ ad_tracking_code: adTrackingCode
685
+ })
686
+
687
+ export const sideBySideSurveyItem = ({
688
+ surveyId,
689
+ threadId,
690
+ botId,
691
+ responseOtid,
692
+ responseTimestampMs,
693
+ simonSessionFbid,
694
+ tessaSessionFbid,
695
+ testArmName
696
+ } = {}) => typed('GenAISideBySideSurveyItem', {
697
+ survey_id: surveyId === undefined ? undefined : String(surveyId),
698
+ thread_id: threadId === undefined ? undefined : String(threadId),
699
+ bot_id: botId === undefined ? undefined : String(botId),
700
+ response_otid: responseOtid,
701
+ response_timestamp_ms: responseTimestampMs,
702
+ simon_session_fbid: simonSessionFbid,
703
+ tessa_session_fbid: tessaSessionFbid,
704
+ test_arm_name: testArmName
705
+ })
706
+
707
+ export const multipleResponseSection = (responses = [], { layoutType = MultipleResponseLayoutType.IN_THREAD, survey } = {}) =>
708
+ layoutSection('MultipleResponse', responses, { layout_type: layoutType, survey_metadata: survey })
709
+
710
+ export const bloomCardSection = (primitives = []) => AIRich.newLayout('IGSuggestedBloomCard', primitives)
711
+
712
+ const ADDON_ACTION_UNSUPPORTED_PRIMITIVES = Object.freeze(['GenAIFooterActionPrimitive'])
713
+
714
+ export const addonActionSection = (primitives = [], { actionType, alignment = AddonActionAlignment.END } = {}) => {
715
+ if (!Object.values(AddonActionType).includes(actionType)) {
716
+ throw new TypeError('addonActionSection actionType must be one of ' + Object.values(AddonActionType).join(', '))
717
+ }
718
+ if (!Array.isArray(primitives) || primitives.length === 0) {
719
+ throw new TypeError('addonActionSection needs at least one overlay button primitive; an empty AddonAction overlay force-closes the recipient')
720
+ }
721
+ for (const primitive of primitives) {
722
+ if (primitive && ADDON_ACTION_UNSUPPORTED_PRIMITIVES.includes(primitive.__typename)) {
723
+ throw new TypeError('addonActionSection cannot render ' + primitive.__typename + '; AddonAction is an overlay whose buttons need a label or icon, and this primitive leaves the button empty so the recipient force-closes. Forward a real Meta AI AddonAction with forwardRichResponse instead of synthesizing one')
724
+ }
725
+ }
726
+ return layoutSection('AddonAction', primitives, { addon_action_type: actionType, addon_action_alignment: alignment })
727
+ }
728
+
729
+ export const QuotaUpsellMeterUsageType = Object.freeze({ META_AI_THINK_HARD: 'META_AI_THINK_HARD' })
730
+
731
+ export const quotaUpsellButton = ({ label, action, deeplink } = {}) =>
732
+ typed('GenAIMetaSubsQuotaUpsellButton', { label, action, deeplink })
733
+
734
+ export const quotaUpsellSection = ({ title, body, bodyLine1, bodyLine2, meterUsageType, benefitType, buttons = [] } = {}) =>
735
+ AIRich.newLayout('Single', typed('GenAIMetaSubsQuotaUpsellPrimitive', {
736
+ title,
737
+ body,
738
+ body_line1: bodyLine1,
739
+ body_line2: bodyLine2,
740
+ meter_usage_type: meterUsageType,
741
+ benefit_type: benefitType,
742
+ buttons: buttons.length ? buttons : undefined
743
+ }))
744
+
745
+ export const quizQuestion = ({ question, options = [], correctIndices = [], explanation, hints = [] } = {}) =>
746
+ typed('GenAIQuizQuestion', {
747
+ question,
748
+ options: options.length ? options : undefined,
749
+ correct_indices: correctIndices.length ? correctIndices : undefined,
750
+ explanation,
751
+ hints: hints.length ? hints : undefined
752
+ })
753
+
754
+ export const quizSection = ({ title, subject, questions = [] } = {}) =>
755
+ AIRich.newLayout('Single', typed('GenAIQuizPrimitive', {
756
+ title,
757
+ subject,
758
+ questions: questions.map(question => (question && question.__typename ? question : quizQuestion(question)))
759
+ }))
760
+
761
+ export const actionGroupButton = ({ actionId, clientActionId, label, deeplink, deeplinkUrl, androidDeeplinkUrl } = {}) =>
762
+ typed('GenAIActionButton', {
763
+ action_id: actionId,
764
+ client_action_id: clientActionId,
765
+ label,
766
+ deeplink,
767
+ deeplink_url: deeplinkUrl,
768
+ android_deeplink_url: androidDeeplinkUrl
769
+ })
770
+
771
+ export const actionGroupSection = ({ groupId, recommendedActionId, buttons = [] } = {}) =>
772
+ AIRich.newLayout('Single', typed('GenAIActionGroupPrimitive', {
773
+ group_id: groupId,
774
+ recommended_action_id: recommendedActionId,
775
+ buttons: buttons.map(button => (button && button.__typename ? button : actionGroupButton(button)))
776
+ }))
777
+
778
+ export const fusedComparisonCta = ({ label, uri } = {}) =>
779
+ typed('GenAIFusedComparisonCTA', { label, uri })
780
+
781
+ export const fusedComparisonColumn = ({ productId, title, productUrl, merchant, image, price, originalPrice, cta } = {}) =>
782
+ typed('GenAIFusedComparisonColumn', {
783
+ product_id: productId === undefined ? undefined : String(productId),
784
+ title,
785
+ product_url: productUrl,
786
+ merchant,
787
+ image,
788
+ price,
789
+ original_price: originalPrice,
790
+ cta: cta && cta.__typename ? cta : cta ? fusedComparisonCta(cta) : undefined
791
+ })
792
+
793
+ export const fusedComparisonRow = ({ label, cells = [] } = {}) =>
794
+ typed('GenAIFusedComparisonRow', {
795
+ label,
796
+ cells: cells.length ? cells : undefined
797
+ })
798
+
799
+ export const fusedComparisonSection = ({ columns = [], rows = [], labelColumnIndex, pinLabelColumn } = {}) =>
800
+ AIRich.newLayout('Single', typed('GenAIFusedComparisonTablePrimitive', {
801
+ columns: columns.map(column => (column && column.__typename ? column : fusedComparisonColumn(column))),
802
+ rows: rows.map(row => (row && row.__typename ? row : fusedComparisonRow(row))),
803
+ label_column_index: labelColumnIndex,
804
+ pin_label_column: pinLabelColumn
805
+ }))
806
+
807
+ const toBytes = (value) => {
808
+ if (value === undefined || value === null) {
809
+ return undefined
810
+ }
811
+ if (Buffer.isBuffer(value)) {
812
+ return Buffer.from(value)
813
+ }
814
+ if (value instanceof Uint8Array) {
815
+ return Buffer.from(value)
816
+ }
817
+ return Buffer.from(String(value), 'base64')
818
+ }
819
+
820
+ const richResponseOf = (msg) => {
821
+ const message = msg?.message ?? msg
822
+ if (!message) {
823
+ return { message: undefined, richResponseMessage: undefined }
824
+ }
825
+ const inner = message.botForwardedMessage?.message ?? message.botForwardedMessage ?? message
826
+ return { message, richResponseMessage: inner?.richResponseMessage }
827
+ }
828
+
829
+ export const readSignedRichResponse = (msg) => {
830
+ const { message, richResponseMessage } = richResponseOf(msg)
831
+ if (!richResponseMessage) {
832
+ return null
833
+ }
834
+ const botMetadata = message.messageContextInfo?.botMetadata
835
+ const proofs = botMetadata?.verificationMetadata?.proofs ?? []
836
+ const proof = proofs.find(item => Number(item?.useCase) === BOT_SIGNATURE_USE_CASE_WA_BOT_MSG)
837
+ const data = toBytes(richResponseMessage.unifiedResponse?.data)
838
+ return {
839
+ richResponseMessage,
840
+ botMetadata,
841
+ botJid: richResponseMessage.contextInfo?.forwardedAiBotMessageInfo?.botJid,
842
+ unifiedResponseBytes: data,
843
+ proof,
844
+ hasProof: !!(proof?.signature?.length && proof?.certificateChain?.length && data?.length)
845
+ }
846
+ }
847
+
848
+ export const verifyRichResponseSignature = (msg, { at } = {}) => {
849
+ const signed = readSignedRichResponse(msg)
850
+ if (!signed) {
851
+ return { status: 'failed', reason: 'not a rich response' }
852
+ }
853
+ return verifyBotSignature({
854
+ botJid: signed.botJid,
855
+ unifiedResponseBytes: signed.unifiedResponseBytes,
856
+ proof: signed.proof,
857
+ at
858
+ })
859
+ }
860
+
861
+ export const forwardRichResponse = async (sock, jid, msg, { quoted, contextInfo, messageId, additionalNodes = [], forwardWrapper = true, ...options } = {}) => {
862
+ const signed = readSignedRichResponse(msg)
863
+ if (!signed) {
864
+ throw new TypeError('forwardRichResponse needs a message carrying a richResponseMessage')
865
+ }
866
+ const { richResponseMessage, botMetadata } = signed
867
+ const relayed = {
868
+ ...structuredClone(richResponseMessage),
869
+ unifiedResponse: signed.unifiedResponseBytes === undefined
870
+ ? richResponseMessage.unifiedResponse
871
+ : { data: signed.unifiedResponseBytes },
872
+ contextInfo: {
873
+ ...structuredClone(richResponseMessage.contextInfo ?? {}),
874
+ ...(contextInfo ?? {}),
875
+ ...(quoted
876
+ ? {
877
+ stanzaId: quoted.key?.id ?? quoted.id,
878
+ participant: quoted.key?.participant ?? quoted.participant ?? quoted.key?.remoteJid,
879
+ quotedMessage: quoted.message ?? quoted
880
+ }
881
+ : {})
882
+ }
883
+ }
884
+ const content = {
885
+ ...(botMetadata ? { messageContextInfo: structuredClone(msg?.message?.messageContextInfo ?? msg?.messageContextInfo ?? {}) } : {}),
886
+ ...AIRich.wrapRichResponse(relayed, forwardWrapper)
887
+ }
888
+ const built = generateWAMessageFromContent(jid, content, { messageId, ...options })
889
+ await sock.relayMessage(jid, built.message, { messageId: built.key.id, additionalNodes })
890
+ return built
891
+ }