nodejs-insta-private-api-mqt 1.3.83 → 1.3.84

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 (392) hide show
  1. package/dist-ts/dist/constants/constants.js +341 -0
  2. package/dist-ts/dist/constants/index.js +53 -0
  3. package/dist-ts/dist/core/client.js +437 -0
  4. package/dist-ts/dist/core/nav-chain.js +252 -0
  5. package/dist-ts/dist/core/repository.js +6 -0
  6. package/dist-ts/dist/core/request.js +358 -0
  7. package/dist-ts/dist/core/state.js +1428 -0
  8. package/dist-ts/dist/core/utils.js +723 -0
  9. package/dist-ts/dist/downloadMedia.js +336 -0
  10. package/dist-ts/dist/errors/index.js +37 -0
  11. package/dist-ts/dist/extend.js +157 -0
  12. package/dist-ts/dist/fbns/fbns.client.events.js +2 -0
  13. package/dist-ts/dist/fbns/fbns.client.js +237 -0
  14. package/dist-ts/dist/fbns/fbns.device-auth.js +59 -0
  15. package/dist-ts/dist/fbns/fbns.types.js +2 -0
  16. package/dist-ts/dist/fbns/fbns.utilities.js +78 -0
  17. package/dist-ts/dist/fbns/index.js +24 -0
  18. package/dist-ts/dist/index.js +137 -0
  19. package/dist-ts/dist/mqtt-shim.js +14 -0
  20. package/dist-ts/dist/mqttot/index.js +24 -0
  21. package/dist-ts/dist/mqttot/mqttot.client.js +322 -0
  22. package/dist-ts/dist/mqttot/mqttot.connect.request.packet.js +8 -0
  23. package/dist-ts/dist/mqttot/mqttot.connect.response.packet.js +23 -0
  24. package/dist-ts/dist/mqttot/mqttot.connection.js +68 -0
  25. package/dist-ts/dist/realtime/commands/commands.js +67 -0
  26. package/dist-ts/dist/realtime/commands/direct.commands.js +415 -0
  27. package/dist-ts/dist/realtime/commands/enhanced.direct.commands.js +1529 -0
  28. package/dist-ts/dist/realtime/commands/index.js +23 -0
  29. package/dist-ts/dist/realtime/delta-sync.manager.js +260 -0
  30. package/dist-ts/dist/realtime/features/dm-sender.js +94 -0
  31. package/dist-ts/dist/realtime/features/error-handler.js +167 -0
  32. package/dist-ts/dist/realtime/features/gap-handler.js +60 -0
  33. package/dist-ts/dist/realtime/features/persistent-logger.js +174 -0
  34. package/dist-ts/dist/realtime/features/presence.manager.js +68 -0
  35. package/dist-ts/dist/realtime/features/session-health-monitor.js +327 -0
  36. package/dist-ts/dist/realtime/index.js +21 -0
  37. package/dist-ts/dist/realtime/messages/app-presence.event.js +2 -0
  38. package/dist-ts/dist/realtime/messages/index.js +23 -0
  39. package/dist-ts/dist/realtime/messages/message-sync.message.js +42 -0
  40. package/dist-ts/dist/realtime/messages/realtime-sub.direct.data.js +2 -0
  41. package/dist-ts/dist/realtime/messages/thread-update.message.js +2 -0
  42. package/dist-ts/dist/realtime/mixins/index.js +23 -0
  43. package/dist-ts/dist/realtime/mixins/message-sync.mixin.js +585 -0
  44. package/dist-ts/dist/realtime/mixins/mixin.js +40 -0
  45. package/dist-ts/dist/realtime/mixins/presence-typing.mixin.js +29 -0
  46. package/dist-ts/dist/realtime/mixins/realtime-sub.mixin.js +171 -0
  47. package/dist-ts/dist/realtime/parsers/graphql-parser.js +43 -0
  48. package/dist-ts/dist/realtime/parsers/graphql.parser.js +22 -0
  49. package/dist-ts/dist/realtime/parsers/index.js +26 -0
  50. package/dist-ts/dist/realtime/parsers/iris-parser.js +43 -0
  51. package/dist-ts/dist/realtime/parsers/iris.parser.js +9 -0
  52. package/dist-ts/dist/realtime/parsers/json-parser.js +43 -0
  53. package/dist-ts/dist/realtime/parsers/json.parser.js +9 -0
  54. package/dist-ts/dist/realtime/parsers/parser.js +2 -0
  55. package/dist-ts/dist/realtime/parsers/region-hint-parser.js +43 -0
  56. package/dist-ts/dist/realtime/parsers/region-hint.parser.js +14 -0
  57. package/dist-ts/dist/realtime/parsers/skywalker-parser.js +43 -0
  58. package/dist-ts/dist/realtime/parsers/skywalker.parser.js +14 -0
  59. package/dist-ts/dist/realtime/parsers-advanced.js +138 -0
  60. package/dist-ts/dist/realtime/proto-parser.js +186 -0
  61. package/dist-ts/dist/realtime/protocols/iris.handshake.js +76 -0
  62. package/dist-ts/dist/realtime/protocols/skywalker.protocol.js +96 -0
  63. package/dist-ts/dist/realtime/realtime.client.events.js +2 -0
  64. package/dist-ts/dist/realtime/realtime.client.js +2117 -0
  65. package/dist-ts/dist/realtime/realtime.service.js +408 -0
  66. package/dist-ts/dist/realtime/reconnect.manager.js +72 -0
  67. package/dist-ts/dist/realtime/session.manager.js +106 -0
  68. package/dist-ts/dist/realtime/subscriptions/graphql.subscription.js +98 -0
  69. package/dist-ts/dist/realtime/subscriptions/index.js +22 -0
  70. package/dist-ts/dist/realtime/subscriptions/skywalker.subscription.js +12 -0
  71. package/dist-ts/dist/realtime/topic-map.js +57 -0
  72. package/dist-ts/dist/realtime/topic.js +76 -0
  73. package/dist-ts/dist/repositories/account.repository.js +1267 -0
  74. package/dist-ts/dist/repositories/bloks.repository.js +66 -0
  75. package/dist-ts/dist/repositories/captcha.repository.js +40 -0
  76. package/dist-ts/dist/repositories/challenge.repository.js +108 -0
  77. package/dist-ts/dist/repositories/clip.repository.js +134 -0
  78. package/dist-ts/dist/repositories/close-friends.repository.js +41 -0
  79. package/dist-ts/dist/repositories/collection.repository.js +64 -0
  80. package/dist-ts/dist/repositories/direct-thread.repository.js +423 -0
  81. package/dist-ts/dist/repositories/direct.repository.js +246 -0
  82. package/dist-ts/dist/repositories/explore.repository.js +60 -0
  83. package/dist-ts/dist/repositories/fbsearch.repository.js +124 -0
  84. package/dist-ts/dist/repositories/feed.repository.js +237 -0
  85. package/dist-ts/dist/repositories/friendship.repository.js +277 -0
  86. package/dist-ts/dist/repositories/fundraiser.repository.js +38 -0
  87. package/dist-ts/dist/repositories/hashtag.repository.js +80 -0
  88. package/dist-ts/dist/repositories/highlights.repository.js +100 -0
  89. package/dist-ts/dist/repositories/insights.repository.js +66 -0
  90. package/dist-ts/dist/repositories/location.repository.js +67 -0
  91. package/dist-ts/dist/repositories/media.repository.js +370 -0
  92. package/dist-ts/dist/repositories/multiple-accounts.repository.js +36 -0
  93. package/dist-ts/dist/repositories/news.repository.js +32 -0
  94. package/dist-ts/dist/repositories/note.repository.js +51 -0
  95. package/dist-ts/dist/repositories/notification.repository.js +77 -0
  96. package/dist-ts/dist/repositories/share.repository.js +34 -0
  97. package/dist-ts/dist/repositories/signup.repository.js +178 -0
  98. package/dist-ts/dist/repositories/story.repository.js +268 -0
  99. package/dist-ts/dist/repositories/timeline.repository.js +57 -0
  100. package/dist-ts/dist/repositories/totp.repository.js +124 -0
  101. package/dist-ts/dist/repositories/track.repository.js +50 -0
  102. package/dist-ts/dist/repositories/upload.repository.js +191 -0
  103. package/dist-ts/dist/repositories/user.repository.js +332 -0
  104. package/dist-ts/dist/sendmedia/index.js +24 -0
  105. package/dist-ts/dist/sendmedia/sendFile.js +56 -0
  106. package/dist-ts/dist/sendmedia/sendPhoto.js +132 -0
  107. package/dist-ts/dist/sendmedia/sendRavenPhoto.js +133 -0
  108. package/dist-ts/dist/sendmedia/sendRavenVideo.js +136 -0
  109. package/dist-ts/dist/sendmedia/uploadPhoto.js +89 -0
  110. package/dist-ts/dist/sendmedia/uploadfFile.js +108 -0
  111. package/dist-ts/dist/services/live.service.js +113 -0
  112. package/dist-ts/dist/services/search.service.js +91 -0
  113. package/dist-ts/dist/shared/index.js +98 -0
  114. package/dist-ts/dist/shared/shared.js +85 -0
  115. package/dist-ts/dist/thrift/index.js +23 -0
  116. package/dist-ts/dist/thrift/thrift.js +105 -0
  117. package/dist-ts/dist/thrift/thrift.reading.js +339 -0
  118. package/dist-ts/dist/thrift/thrift.writing.js +393 -0
  119. package/dist-ts/dist/types/index.js +276 -0
  120. package/dist-ts/dist/useMultiFileAuthState.js +1878 -0
  121. package/dist-ts/dist/utils/index.js +244 -0
  122. package/dist-ts/examples/listen-to-messages.js +73 -0
  123. package/package.json +1 -1
  124. package/src-ts/dist/realtime/protocols/proto-definitions.ts +80 -0
  125. package/src-ts/dist/utils/helper-1.ts +1 -0
  126. package/src-ts/dist/utils/helper-10.ts +1 -0
  127. package/src-ts/dist/utils/helper-11.ts +1 -0
  128. package/src-ts/dist/utils/helper-12.ts +1 -0
  129. package/src-ts/dist/utils/helper-13.ts +1 -0
  130. package/src-ts/dist/utils/helper-14.ts +1 -0
  131. package/src-ts/dist/utils/helper-15.ts +1 -0
  132. package/src-ts/dist/utils/helper-16.ts +1 -0
  133. package/src-ts/dist/utils/helper-17.ts +1 -0
  134. package/src-ts/dist/utils/helper-18.ts +1 -0
  135. package/src-ts/dist/utils/helper-19.ts +1 -0
  136. package/src-ts/dist/utils/helper-2.ts +1 -0
  137. package/src-ts/dist/utils/helper-20.ts +1 -0
  138. package/src-ts/dist/utils/helper-21.ts +1 -0
  139. package/src-ts/dist/utils/helper-22.ts +1 -0
  140. package/src-ts/dist/utils/helper-23.ts +1 -0
  141. package/src-ts/dist/utils/helper-24.ts +1 -0
  142. package/src-ts/dist/utils/helper-25.ts +1 -0
  143. package/src-ts/dist/utils/helper-26.ts +1 -0
  144. package/src-ts/dist/utils/helper-27.ts +1 -0
  145. package/src-ts/dist/utils/helper-28.ts +1 -0
  146. package/src-ts/dist/utils/helper-29.ts +1 -0
  147. package/src-ts/dist/utils/helper-3.ts +1 -0
  148. package/src-ts/dist/utils/helper-30.ts +1 -0
  149. package/src-ts/dist/utils/helper-4.ts +1 -0
  150. package/src-ts/dist/utils/helper-5.ts +1 -0
  151. package/src-ts/dist/utils/helper-6.ts +1 -0
  152. package/src-ts/dist/utils/helper-7.ts +1 -0
  153. package/src-ts/dist/utils/helper-8.ts +1 -0
  154. package/src-ts/dist/utils/helper-9.ts +1 -0
  155. package/src-ts/dist/utils/insta-mqtt-helper.ts +128 -0
  156. package/src-ts/examples/listen-to-messages.ts +86 -0
  157. package/dist/errors/index.d.ts +0 -16
  158. package/dist/errors/index.js.map +0 -1
  159. package/dist/fbns/fbns.client.d.ts +0 -32
  160. package/dist/fbns/fbns.client.events.d.ts +0 -41
  161. package/dist/fbns/fbns.client.events.js.map +0 -1
  162. package/dist/fbns/fbns.client.js.map +0 -1
  163. package/dist/fbns/fbns.device-auth.d.ts +0 -17
  164. package/dist/fbns/fbns.device-auth.js.map +0 -1
  165. package/dist/fbns/fbns.types.d.ts +0 -83
  166. package/dist/fbns/fbns.types.js.map +0 -1
  167. package/dist/fbns/fbns.utilities.d.ts +0 -2
  168. package/dist/fbns/fbns.utilities.js.map +0 -1
  169. package/dist/fbns/index.d.ts +0 -4
  170. package/dist/fbns/index.js.map +0 -1
  171. package/dist/mqtt-shim.d.ts +0 -96
  172. package/dist/mqttot/index.d.ts +0 -4
  173. package/dist/mqttot/index.js.map +0 -1
  174. package/dist/mqttot/mqttot.client.d.ts +0 -39
  175. package/dist/mqttot/mqttot.client.js.map +0 -1
  176. package/dist/mqttot/mqttot.connect.request.packet.d.ts +0 -7
  177. package/dist/mqttot/mqttot.connect.request.packet.js.map +0 -1
  178. package/dist/mqttot/mqttot.connect.response.packet.d.ts +0 -7
  179. package/dist/mqttot/mqttot.connect.response.packet.js.map +0 -1
  180. package/dist/mqttot/mqttot.connection.d.ts +0 -57
  181. package/dist/mqttot/mqttot.connection.js.map +0 -1
  182. package/dist/package.json +0 -59
  183. package/dist/realtime/commands/commands.d.ts +0 -15
  184. package/dist/realtime/commands/commands.js.map +0 -1
  185. package/dist/realtime/commands/direct.commands.d.ts +0 -75
  186. package/dist/realtime/commands/direct.commands.js.map +0 -1
  187. package/dist/realtime/commands/enhanced.direct.commands.js.bak +0 -967
  188. package/dist/realtime/commands/index.d.ts +0 -2
  189. package/dist/realtime/commands/index.js.map +0 -1
  190. package/dist/realtime/messages/app-presence.event.d.ts +0 -9
  191. package/dist/realtime/messages/app-presence.event.js.map +0 -1
  192. package/dist/realtime/messages/index.d.ts +0 -3
  193. package/dist/realtime/messages/index.js.map +0 -1
  194. package/dist/realtime/messages/message-sync.message.d.ts +0 -222
  195. package/dist/realtime/messages/message-sync.message.js.map +0 -1
  196. package/dist/realtime/messages/realtime-sub.direct.data.d.ts +0 -11
  197. package/dist/realtime/messages/realtime-sub.direct.data.js.map +0 -1
  198. package/dist/realtime/messages/thread-update.message.d.ts +0 -68
  199. package/dist/realtime/messages/thread-update.message.js.map +0 -1
  200. package/dist/realtime/mixins/index.d.ts +0 -3
  201. package/dist/realtime/mixins/index.js.map +0 -1
  202. package/dist/realtime/mixins/message-sync.mixin.d.ts +0 -8
  203. package/dist/realtime/mixins/message-sync.mixin.js.map +0 -1
  204. package/dist/realtime/mixins/mixin.d.ts +0 -19
  205. package/dist/realtime/mixins/mixin.js.map +0 -1
  206. package/dist/realtime/mixins/realtime-sub.mixin.d.ts +0 -8
  207. package/dist/realtime/mixins/realtime-sub.mixin.js.map +0 -1
  208. package/dist/realtime/parsers/graphql.parser.d.ts +0 -15
  209. package/dist/realtime/parsers/graphql.parser.js.map +0 -1
  210. package/dist/realtime/parsers/index.d.ts +0 -6
  211. package/dist/realtime/parsers/index.js.map +0 -1
  212. package/dist/realtime/parsers/iris.parser.d.ts +0 -17
  213. package/dist/realtime/parsers/iris.parser.js.map +0 -1
  214. package/dist/realtime/parsers/json.parser.d.ts +0 -6
  215. package/dist/realtime/parsers/json.parser.js.map +0 -1
  216. package/dist/realtime/parsers/parser.d.ts +0 -9
  217. package/dist/realtime/parsers/parser.js.map +0 -1
  218. package/dist/realtime/parsers/region-hint.parser.d.ts +0 -12
  219. package/dist/realtime/parsers/region-hint.parser.js.map +0 -1
  220. package/dist/realtime/parsers/skywalker.parser.d.ts +0 -12
  221. package/dist/realtime/parsers/skywalker.parser.js.map +0 -1
  222. package/dist/realtime/proto/common.proto +0 -38
  223. package/dist/realtime/proto/direct.proto +0 -65
  224. package/dist/realtime/proto/ig-messages.proto +0 -83
  225. package/dist/realtime/proto/iris.proto +0 -188
  226. package/dist/realtime/subscriptions/graphql.subscription.d.ts +0 -47
  227. package/dist/realtime/subscriptions/graphql.subscription.js.map +0 -1
  228. package/dist/realtime/subscriptions/index.d.ts +0 -2
  229. package/dist/realtime/subscriptions/index.js.map +0 -1
  230. package/dist/realtime/subscriptions/skywalker.subscription.d.ts +0 -4
  231. package/dist/realtime/subscriptions/skywalker.subscription.js.map +0 -1
  232. package/dist/thrift/index.d.ts +0 -3
  233. package/dist/thrift/index.js.map +0 -1
  234. package/dist/thrift/thrift.d.ts +0 -59
  235. package/dist/thrift/thrift.js.map +0 -1
  236. package/dist/thrift/thrift.reading.d.ts +0 -41
  237. package/dist/thrift/thrift.reading.js.map +0 -1
  238. package/dist/thrift/thrift.writing.d.ts +0 -44
  239. package/dist/thrift/thrift.writing.js.map +0 -1
  240. /package/{dist → dist-ts/dist}/realtime/protocols/proto-definitions.js +0 -0
  241. /package/{dist → dist-ts/dist}/utils/helper-1.js +0 -0
  242. /package/{dist → dist-ts/dist}/utils/helper-10.js +0 -0
  243. /package/{dist → dist-ts/dist}/utils/helper-11.js +0 -0
  244. /package/{dist → dist-ts/dist}/utils/helper-12.js +0 -0
  245. /package/{dist → dist-ts/dist}/utils/helper-13.js +0 -0
  246. /package/{dist → dist-ts/dist}/utils/helper-14.js +0 -0
  247. /package/{dist → dist-ts/dist}/utils/helper-15.js +0 -0
  248. /package/{dist → dist-ts/dist}/utils/helper-16.js +0 -0
  249. /package/{dist → dist-ts/dist}/utils/helper-17.js +0 -0
  250. /package/{dist → dist-ts/dist}/utils/helper-18.js +0 -0
  251. /package/{dist → dist-ts/dist}/utils/helper-19.js +0 -0
  252. /package/{dist → dist-ts/dist}/utils/helper-2.js +0 -0
  253. /package/{dist → dist-ts/dist}/utils/helper-20.js +0 -0
  254. /package/{dist → dist-ts/dist}/utils/helper-21.js +0 -0
  255. /package/{dist → dist-ts/dist}/utils/helper-22.js +0 -0
  256. /package/{dist → dist-ts/dist}/utils/helper-23.js +0 -0
  257. /package/{dist → dist-ts/dist}/utils/helper-24.js +0 -0
  258. /package/{dist → dist-ts/dist}/utils/helper-25.js +0 -0
  259. /package/{dist → dist-ts/dist}/utils/helper-26.js +0 -0
  260. /package/{dist → dist-ts/dist}/utils/helper-27.js +0 -0
  261. /package/{dist → dist-ts/dist}/utils/helper-28.js +0 -0
  262. /package/{dist → dist-ts/dist}/utils/helper-29.js +0 -0
  263. /package/{dist → dist-ts/dist}/utils/helper-3.js +0 -0
  264. /package/{dist → dist-ts/dist}/utils/helper-30.js +0 -0
  265. /package/{dist → dist-ts/dist}/utils/helper-4.js +0 -0
  266. /package/{dist → dist-ts/dist}/utils/helper-5.js +0 -0
  267. /package/{dist → dist-ts/dist}/utils/helper-6.js +0 -0
  268. /package/{dist → dist-ts/dist}/utils/helper-7.js +0 -0
  269. /package/{dist → dist-ts/dist}/utils/helper-8.js +0 -0
  270. /package/{dist → dist-ts/dist}/utils/helper-9.js +0 -0
  271. /package/{dist → dist-ts/dist}/utils/insta-mqtt-helper.js +0 -0
  272. /package/{dist/constants/constants.js → src-ts/dist/constants/constants.ts} +0 -0
  273. /package/{dist/constants/index.js → src-ts/dist/constants/index.ts} +0 -0
  274. /package/{dist/core/client.js → src-ts/dist/core/client.ts} +0 -0
  275. /package/{dist/core/nav-chain.js → src-ts/dist/core/nav-chain.ts} +0 -0
  276. /package/{dist/core/repository.js → src-ts/dist/core/repository.ts} +0 -0
  277. /package/{dist/core/request.js → src-ts/dist/core/request.ts} +0 -0
  278. /package/{dist/core/state.js → src-ts/dist/core/state.ts} +0 -0
  279. /package/{dist/core/utils.js → src-ts/dist/core/utils.ts} +0 -0
  280. /package/{dist/downloadMedia.js → src-ts/dist/downloadMedia.ts} +0 -0
  281. /package/{dist/errors/index.js → src-ts/dist/errors/index.ts} +0 -0
  282. /package/{dist/extend.js → src-ts/dist/extend.ts} +0 -0
  283. /package/{dist/fbns/fbns.client.events.js → src-ts/dist/fbns/fbns.client.events.ts} +0 -0
  284. /package/{dist/fbns/fbns.client.js → src-ts/dist/fbns/fbns.client.ts} +0 -0
  285. /package/{dist/fbns/fbns.device-auth.js → src-ts/dist/fbns/fbns.device-auth.ts} +0 -0
  286. /package/{dist/fbns/fbns.types.js → src-ts/dist/fbns/fbns.types.ts} +0 -0
  287. /package/{dist/fbns/fbns.utilities.js → src-ts/dist/fbns/fbns.utilities.ts} +0 -0
  288. /package/{dist/fbns/index.js → src-ts/dist/fbns/index.ts} +0 -0
  289. /package/{dist/index.js → src-ts/dist/index.ts} +0 -0
  290. /package/{dist/mqtt-shim.js → src-ts/dist/mqtt-shim.ts} +0 -0
  291. /package/{dist/mqttot/index.js → src-ts/dist/mqttot/index.ts} +0 -0
  292. /package/{dist/mqttot/mqttot.client.js → src-ts/dist/mqttot/mqttot.client.ts} +0 -0
  293. /package/{dist/mqttot/mqttot.connect.request.packet.js → src-ts/dist/mqttot/mqttot.connect.request.packet.ts} +0 -0
  294. /package/{dist/mqttot/mqttot.connect.response.packet.js → src-ts/dist/mqttot/mqttot.connect.response.packet.ts} +0 -0
  295. /package/{dist/mqttot/mqttot.connection.js → src-ts/dist/mqttot/mqttot.connection.ts} +0 -0
  296. /package/{dist/realtime/commands/commands.js → src-ts/dist/realtime/commands/commands.ts} +0 -0
  297. /package/{dist/realtime/commands/direct.commands.js → src-ts/dist/realtime/commands/direct.commands.ts} +0 -0
  298. /package/{dist/realtime/commands/enhanced.direct.commands.js → src-ts/dist/realtime/commands/enhanced.direct.commands.ts} +0 -0
  299. /package/{dist/realtime/commands/index.js → src-ts/dist/realtime/commands/index.ts} +0 -0
  300. /package/{dist/realtime/delta-sync.manager.js → src-ts/dist/realtime/delta-sync.manager.ts} +0 -0
  301. /package/{dist/realtime/features/dm-sender.js → src-ts/dist/realtime/features/dm-sender.ts} +0 -0
  302. /package/{dist/realtime/features/error-handler.js → src-ts/dist/realtime/features/error-handler.ts} +0 -0
  303. /package/{dist/realtime/features/gap-handler.js → src-ts/dist/realtime/features/gap-handler.ts} +0 -0
  304. /package/{dist/realtime/features/persistent-logger.js → src-ts/dist/realtime/features/persistent-logger.ts} +0 -0
  305. /package/{dist/realtime/features/presence.manager.js → src-ts/dist/realtime/features/presence.manager.ts} +0 -0
  306. /package/{dist/realtime/features/session-health-monitor.js → src-ts/dist/realtime/features/session-health-monitor.ts} +0 -0
  307. /package/{dist/realtime/index.js → src-ts/dist/realtime/index.ts} +0 -0
  308. /package/{dist/realtime/messages/app-presence.event.js → src-ts/dist/realtime/messages/app-presence.event.ts} +0 -0
  309. /package/{dist/realtime/messages/index.js → src-ts/dist/realtime/messages/index.ts} +0 -0
  310. /package/{dist/realtime/messages/message-sync.message.js → src-ts/dist/realtime/messages/message-sync.message.ts} +0 -0
  311. /package/{dist/realtime/messages/realtime-sub.direct.data.js → src-ts/dist/realtime/messages/realtime-sub.direct.data.ts} +0 -0
  312. /package/{dist/realtime/messages/thread-update.message.js → src-ts/dist/realtime/messages/thread-update.message.ts} +0 -0
  313. /package/{dist/realtime/mixins/index.js → src-ts/dist/realtime/mixins/index.ts} +0 -0
  314. /package/{dist/realtime/mixins/message-sync.mixin.js → src-ts/dist/realtime/mixins/message-sync.mixin.ts} +0 -0
  315. /package/{dist/realtime/mixins/mixin.js → src-ts/dist/realtime/mixins/mixin.ts} +0 -0
  316. /package/{dist/realtime/mixins/presence-typing.mixin.js → src-ts/dist/realtime/mixins/presence-typing.mixin.ts} +0 -0
  317. /package/{dist/realtime/mixins/realtime-sub.mixin.js → src-ts/dist/realtime/mixins/realtime-sub.mixin.ts} +0 -0
  318. /package/{dist/realtime/parsers/graphql-parser.js → src-ts/dist/realtime/parsers/graphql-parser.ts} +0 -0
  319. /package/{dist/realtime/parsers/graphql.parser.js → src-ts/dist/realtime/parsers/graphql.parser.ts} +0 -0
  320. /package/{dist/realtime/parsers/index.js → src-ts/dist/realtime/parsers/index.ts} +0 -0
  321. /package/{dist/realtime/parsers/iris-parser.js → src-ts/dist/realtime/parsers/iris-parser.ts} +0 -0
  322. /package/{dist/realtime/parsers/iris.parser.js → src-ts/dist/realtime/parsers/iris.parser.ts} +0 -0
  323. /package/{dist/realtime/parsers/json-parser.js → src-ts/dist/realtime/parsers/json-parser.ts} +0 -0
  324. /package/{dist/realtime/parsers/json.parser.js → src-ts/dist/realtime/parsers/json.parser.ts} +0 -0
  325. /package/{dist/realtime/parsers/parser.js → src-ts/dist/realtime/parsers/parser.ts} +0 -0
  326. /package/{dist/realtime/parsers/region-hint-parser.js → src-ts/dist/realtime/parsers/region-hint-parser.ts} +0 -0
  327. /package/{dist/realtime/parsers/region-hint.parser.js → src-ts/dist/realtime/parsers/region-hint.parser.ts} +0 -0
  328. /package/{dist/realtime/parsers/skywalker-parser.js → src-ts/dist/realtime/parsers/skywalker-parser.ts} +0 -0
  329. /package/{dist/realtime/parsers/skywalker.parser.js → src-ts/dist/realtime/parsers/skywalker.parser.ts} +0 -0
  330. /package/{dist/realtime/parsers-advanced.js → src-ts/dist/realtime/parsers-advanced.ts} +0 -0
  331. /package/{dist/realtime/proto-parser.js → src-ts/dist/realtime/proto-parser.ts} +0 -0
  332. /package/{dist/realtime/protocols/iris.handshake.js → src-ts/dist/realtime/protocols/iris.handshake.ts} +0 -0
  333. /package/{dist/realtime/protocols/skywalker.protocol.js → src-ts/dist/realtime/protocols/skywalker.protocol.ts} +0 -0
  334. /package/{dist/realtime/realtime.client.events.js → src-ts/dist/realtime/realtime.client.events.ts} +0 -0
  335. /package/{dist/realtime/realtime.client.js → src-ts/dist/realtime/realtime.client.ts} +0 -0
  336. /package/{dist/realtime/realtime.service.js → src-ts/dist/realtime/realtime.service.ts} +0 -0
  337. /package/{dist/realtime/reconnect.manager.js → src-ts/dist/realtime/reconnect.manager.ts} +0 -0
  338. /package/{dist/realtime/session.manager.js → src-ts/dist/realtime/session.manager.ts} +0 -0
  339. /package/{dist/realtime/subscriptions/graphql.subscription.js → src-ts/dist/realtime/subscriptions/graphql.subscription.ts} +0 -0
  340. /package/{dist/realtime/subscriptions/index.js → src-ts/dist/realtime/subscriptions/index.ts} +0 -0
  341. /package/{dist/realtime/subscriptions/skywalker.subscription.js → src-ts/dist/realtime/subscriptions/skywalker.subscription.ts} +0 -0
  342. /package/{dist/realtime/topic-map.js → src-ts/dist/realtime/topic-map.ts} +0 -0
  343. /package/{dist/realtime/topic.js → src-ts/dist/realtime/topic.ts} +0 -0
  344. /package/{dist/repositories/account.repository.js → src-ts/dist/repositories/account.repository.ts} +0 -0
  345. /package/{dist/repositories/bloks.repository.js → src-ts/dist/repositories/bloks.repository.ts} +0 -0
  346. /package/{dist/repositories/captcha.repository.js → src-ts/dist/repositories/captcha.repository.ts} +0 -0
  347. /package/{dist/repositories/challenge.repository.js → src-ts/dist/repositories/challenge.repository.ts} +0 -0
  348. /package/{dist/repositories/clip.repository.js → src-ts/dist/repositories/clip.repository.ts} +0 -0
  349. /package/{dist/repositories/close-friends.repository.js → src-ts/dist/repositories/close-friends.repository.ts} +0 -0
  350. /package/{dist/repositories/collection.repository.js → src-ts/dist/repositories/collection.repository.ts} +0 -0
  351. /package/{dist/repositories/direct-thread.repository.js → src-ts/dist/repositories/direct-thread.repository.ts} +0 -0
  352. /package/{dist/repositories/direct.repository.js → src-ts/dist/repositories/direct.repository.ts} +0 -0
  353. /package/{dist/repositories/explore.repository.js → src-ts/dist/repositories/explore.repository.ts} +0 -0
  354. /package/{dist/repositories/fbsearch.repository.js → src-ts/dist/repositories/fbsearch.repository.ts} +0 -0
  355. /package/{dist/repositories/feed.repository.js → src-ts/dist/repositories/feed.repository.ts} +0 -0
  356. /package/{dist/repositories/friendship.repository.js → src-ts/dist/repositories/friendship.repository.ts} +0 -0
  357. /package/{dist/repositories/fundraiser.repository.js → src-ts/dist/repositories/fundraiser.repository.ts} +0 -0
  358. /package/{dist/repositories/hashtag.repository.js → src-ts/dist/repositories/hashtag.repository.ts} +0 -0
  359. /package/{dist/repositories/highlights.repository.js → src-ts/dist/repositories/highlights.repository.ts} +0 -0
  360. /package/{dist/repositories/insights.repository.js → src-ts/dist/repositories/insights.repository.ts} +0 -0
  361. /package/{dist/repositories/location.repository.js → src-ts/dist/repositories/location.repository.ts} +0 -0
  362. /package/{dist/repositories/media.repository.js → src-ts/dist/repositories/media.repository.ts} +0 -0
  363. /package/{dist/repositories/multiple-accounts.repository.js → src-ts/dist/repositories/multiple-accounts.repository.ts} +0 -0
  364. /package/{dist/repositories/news.repository.js → src-ts/dist/repositories/news.repository.ts} +0 -0
  365. /package/{dist/repositories/note.repository.js → src-ts/dist/repositories/note.repository.ts} +0 -0
  366. /package/{dist/repositories/notification.repository.js → src-ts/dist/repositories/notification.repository.ts} +0 -0
  367. /package/{dist/repositories/share.repository.js → src-ts/dist/repositories/share.repository.ts} +0 -0
  368. /package/{dist/repositories/signup.repository.js → src-ts/dist/repositories/signup.repository.ts} +0 -0
  369. /package/{dist/repositories/story.repository.js → src-ts/dist/repositories/story.repository.ts} +0 -0
  370. /package/{dist/repositories/timeline.repository.js → src-ts/dist/repositories/timeline.repository.ts} +0 -0
  371. /package/{dist/repositories/totp.repository.js → src-ts/dist/repositories/totp.repository.ts} +0 -0
  372. /package/{dist/repositories/track.repository.js → src-ts/dist/repositories/track.repository.ts} +0 -0
  373. /package/{dist/repositories/upload.repository.js → src-ts/dist/repositories/upload.repository.ts} +0 -0
  374. /package/{dist/repositories/user.repository.js → src-ts/dist/repositories/user.repository.ts} +0 -0
  375. /package/{dist/sendmedia/index.js → src-ts/dist/sendmedia/index.ts} +0 -0
  376. /package/{dist/sendmedia/sendFile.js → src-ts/dist/sendmedia/sendFile.ts} +0 -0
  377. /package/{dist/sendmedia/sendPhoto.js → src-ts/dist/sendmedia/sendPhoto.ts} +0 -0
  378. /package/{dist/sendmedia/sendRavenPhoto.js → src-ts/dist/sendmedia/sendRavenPhoto.ts} +0 -0
  379. /package/{dist/sendmedia/sendRavenVideo.js → src-ts/dist/sendmedia/sendRavenVideo.ts} +0 -0
  380. /package/{dist/sendmedia/uploadPhoto.js → src-ts/dist/sendmedia/uploadPhoto.ts} +0 -0
  381. /package/{dist/sendmedia/uploadfFile.js → src-ts/dist/sendmedia/uploadfFile.ts} +0 -0
  382. /package/{dist/services/live.service.js → src-ts/dist/services/live.service.ts} +0 -0
  383. /package/{dist/services/search.service.js → src-ts/dist/services/search.service.ts} +0 -0
  384. /package/{dist/shared/index.js → src-ts/dist/shared/index.ts} +0 -0
  385. /package/{dist/shared/shared.js → src-ts/dist/shared/shared.ts} +0 -0
  386. /package/{dist/thrift/index.js → src-ts/dist/thrift/index.ts} +0 -0
  387. /package/{dist/thrift/thrift.reading.js → src-ts/dist/thrift/thrift.reading.ts} +0 -0
  388. /package/{dist/thrift/thrift.js → src-ts/dist/thrift/thrift.ts} +0 -0
  389. /package/{dist/thrift/thrift.writing.js → src-ts/dist/thrift/thrift.writing.ts} +0 -0
  390. /package/{dist/types/index.js → src-ts/dist/types/index.ts} +0 -0
  391. /package/{dist/useMultiFileAuthState.js → src-ts/dist/useMultiFileAuthState.ts} +0 -0
  392. /package/{dist/utils/index.js → src-ts/dist/utils/index.ts} +0 -0
@@ -0,0 +1,1529 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnhancedDirectCommands = void 0;
4
+ const shared_1 = require("../../shared");
5
+ const uuid_1 = require("uuid");
6
+ const constants_1 = require("../../constants");
7
+ const thrift_1 = require("../../thrift");
8
+ /**
9
+ * EnhancedDirectCommands
10
+ *
11
+ * - Full, self-contained class that publishes correctly-formatted payloads to Instagram's
12
+ * Direct MQTT (Thrift + compressed payloads).
13
+ * - Updated sendLocation implementation:
14
+ * 1) try publish a story with a Location sticker (preferred, matches APK behavior)
15
+ * 2) share that story to the thread (reel/media_share)
16
+ * 3) fallback: send a link to /explore/locations/{placeId}/ if (1) fails
17
+ *
18
+ * Note: server-side validation may still reject location stickers in some contexts.
19
+ */
20
+ class EnhancedDirectCommands {
21
+ constructor(client) {
22
+ this.realtimeClient = client;
23
+ this.enhancedDebug = (0, shared_1.debugChannel)('realtime', 'enhanced-commands');
24
+ // Foreground state config for Thrift encoding (matching instagram_mqtt)
25
+ this.foregroundStateConfig = [
26
+ thrift_1.ThriftDescriptors.boolean('inForegroundApp', 1),
27
+ thrift_1.ThriftDescriptors.boolean('inForegroundDevice', 2),
28
+ thrift_1.ThriftDescriptors.int32('keepAliveTimeout', 3),
29
+ thrift_1.ThriftDescriptors.listOfBinary('subscribeTopics', 4),
30
+ thrift_1.ThriftDescriptors.listOfBinary('subscribeGenericTopics', 5),
31
+ thrift_1.ThriftDescriptors.listOfBinary('unsubscribeTopics', 6),
32
+ thrift_1.ThriftDescriptors.listOfBinary('unsubscribeGenericTopics', 7),
33
+ thrift_1.ThriftDescriptors.int64('requestId', 8),
34
+ ];
35
+ }
36
+ /**
37
+ * Attempt to locate the MQTT client object on the realtime client.
38
+ * Many wrappers expose mqtt under different property names.
39
+ */
40
+ getMqtt() {
41
+ const candidates = [
42
+ 'mqtt',
43
+ '_mqtt',
44
+ 'client',
45
+ '_client',
46
+ 'connection',
47
+ 'mqttClient',
48
+ ];
49
+ let mqtt = null;
50
+ for (const key of candidates) {
51
+ if (this.realtimeClient && Object.prototype.hasOwnProperty.call(this.realtimeClient, key) && this.realtimeClient[key]) {
52
+ mqtt = this.realtimeClient[key];
53
+ break;
54
+ }
55
+ }
56
+ // fallback: maybe the realtimeClient itself *is* the mqtt client
57
+ if (!mqtt && this.realtimeClient && typeof this.realtimeClient.publish === 'function') {
58
+ mqtt = this.realtimeClient;
59
+ }
60
+ if (!mqtt || typeof mqtt.publish !== 'function') {
61
+ throw new Error('MQTT client not available or does not expose publish(). Found client keys: ' +
62
+ (this.realtimeClient ? Object.keys(this.realtimeClient).join(',') : 'none'));
63
+ }
64
+ return mqtt;
65
+ }
66
+ /**
67
+ * Robust mqtt publish wrapper - handles both:
68
+ * - mqtt.publish({ topic, payload, qosLevel }) returning a Promise or using callback
69
+ * - mqtt.publish(topic, payload, { qos }, cb)
70
+ */
71
+ async publishToMqtt(mqtt, publishObj) {
72
+ const topic = publishObj.topic;
73
+ const payload = publishObj.payload;
74
+ const qosLevel = typeof publishObj.qosLevel !== 'undefined' ? publishObj.qosLevel : 1;
75
+ // Try object-style publish first (some wrappers expect object)
76
+ try {
77
+ const maybePromise = mqtt.publish({
78
+ topic,
79
+ payload,
80
+ qosLevel,
81
+ });
82
+ if (maybePromise && typeof maybePromise.then === 'function') {
83
+ return await maybePromise;
84
+ }
85
+ // if it returned synchronously, maybe it still used callback style
86
+ return await new Promise((resolve, reject) => {
87
+ try {
88
+ mqtt.publish({ topic, payload, qosLevel }, (err, res) => {
89
+ if (err)
90
+ return reject(err);
91
+ return resolve(res);
92
+ });
93
+ }
94
+ catch (err) {
95
+ reject(err);
96
+ }
97
+ });
98
+ }
99
+ catch (e) {
100
+ // fallthrough to positional try
101
+ }
102
+ // Try positional-style publish (topic, payload, options, callback)
103
+ try {
104
+ return await new Promise((resolve, reject) => {
105
+ try {
106
+ mqtt.publish(topic, payload, { qos: qosLevel }, (err, res) => {
107
+ if (err)
108
+ return reject(err);
109
+ return resolve(res);
110
+ });
111
+ }
112
+ catch (err) {
113
+ reject(err);
114
+ }
115
+ });
116
+ }
117
+ catch (e) {
118
+ // final fallback: some clients return synchronously or throw - try positional without callback
119
+ try {
120
+ const res = mqtt.publish(topic, payload, { qos: qosLevel });
121
+ if (res && typeof res.then === 'function') {
122
+ return await res;
123
+ }
124
+ // last attempt: resolve with returned value
125
+ return res;
126
+ }
127
+ catch (err) {
128
+ // give clear error
129
+ throw new Error(`MQTT publish failed: no known publish signature worked. Errors: ${err && err.message ? err.message : String(err)}`);
130
+ }
131
+ }
132
+ }
133
+ /**
134
+ * Send foreground state via MQTT with Thrift encoding (matching instagram_mqtt)
135
+ */
136
+ async sendForegroundState(state) {
137
+ this.enhancedDebug(`Updated foreground state: ${JSON.stringify(state)}`);
138
+ try {
139
+ const mqtt = this.getMqtt();
140
+ const thriftBuffer = (0, thrift_1.thriftWriteFromObject)(state, this.foregroundStateConfig);
141
+ const concat = Buffer.concat([
142
+ Buffer.alloc(1, 0),
143
+ thriftBuffer
144
+ ]);
145
+ // ensure we pass Buffer to compressDeflate
146
+ const payload = await (0, shared_1.compressDeflate)(concat);
147
+ const result = await this.publishToMqtt(mqtt, {
148
+ topic: constants_1.Topics.FOREGROUND_STATE.id,
149
+ payload: payload,
150
+ qosLevel: 1,
151
+ });
152
+ // Update keepAlive if provided
153
+ if ((0, shared_1.notUndefined)(state.keepAliveTimeout)) {
154
+ mqtt.keepAlive = state.keepAliveTimeout;
155
+ }
156
+ this.enhancedDebug(`✅ Foreground state updated via MQTT!`);
157
+ return result;
158
+ }
159
+ catch (err) {
160
+ this.enhancedDebug(`Foreground state failed: ${err && err.message ? err.message : String(err)}`);
161
+ throw err;
162
+ }
163
+ }
164
+ /**
165
+ * Base command sender (matching instagram_mqtt format)
166
+ * It encodes the command as JSON, compresses, and publishes to SEND_MESSAGE topic.
167
+ */
168
+ async sendCommand({ action, data, threadId, clientContext }) {
169
+ try {
170
+ const mqtt = this.getMqtt();
171
+ if (clientContext) {
172
+ data.client_context = clientContext;
173
+ }
174
+ const json = JSON.stringify({
175
+ action,
176
+ thread_id: threadId,
177
+ ...data,
178
+ });
179
+ // ensure Buffer (some compress implementations expect Buffer)
180
+ const payload = await (0, shared_1.compressDeflate)(Buffer.from(json));
181
+ return this.publishToMqtt(mqtt, {
182
+ topic: constants_1.Topics.SEND_MESSAGE.id,
183
+ qosLevel: 1,
184
+ payload: payload,
185
+ });
186
+ }
187
+ catch (err) {
188
+ this.enhancedDebug(`sendCommand failed: ${err && err.message ? err.message : String(err)}`);
189
+ throw err;
190
+ }
191
+ }
192
+ /**
193
+ * Base item sender (matching instagram_mqtt format)
194
+ */
195
+ async sendItem({ threadId, itemType, data, clientContext }) {
196
+ return this.sendCommand({
197
+ action: 'send_item',
198
+ threadId,
199
+ clientContext: clientContext || (0, uuid_1.v4)(),
200
+ data: {
201
+ item_type: itemType,
202
+ ...data,
203
+ },
204
+ });
205
+ }
206
+ /**
207
+ * Send text via MQTT
208
+ */
209
+ async sendText({ text, clientContext, threadId }) {
210
+ this.enhancedDebug(`Sending text to ${threadId}: "${text}"`);
211
+ const result = await this.sendItem({
212
+ itemType: 'text',
213
+ threadId,
214
+ clientContext,
215
+ data: {
216
+ text,
217
+ },
218
+ });
219
+ this.enhancedDebug(`✅ Text sent via MQTT!`);
220
+ return result;
221
+ }
222
+ /**
223
+ * Alias for sendText
224
+ */
225
+ async sendTextViaRealtime(threadId, text, clientContext) {
226
+ return this.sendText({
227
+ text,
228
+ threadId,
229
+ clientContext,
230
+ });
231
+ }
232
+ /**
233
+ * Send hashtag via MQTT
234
+ */
235
+ async sendHashtag({ text, threadId, hashtag, clientContext }) {
236
+ this.enhancedDebug(`Sending hashtag #${hashtag} to ${threadId}`);
237
+ const result = await this.sendItem({
238
+ itemType: 'hashtag',
239
+ threadId,
240
+ clientContext,
241
+ data: {
242
+ text: text || '',
243
+ hashtag,
244
+ item_id: hashtag,
245
+ },
246
+ });
247
+ this.enhancedDebug(`✅ Hashtag sent via MQTT!`);
248
+ return result;
249
+ }
250
+ /**
251
+ * Send like via MQTT
252
+ */
253
+ async sendLike({ threadId, clientContext }) {
254
+ this.enhancedDebug(`Sending like in thread ${threadId}`);
255
+ const result = await this.sendItem({
256
+ itemType: 'like',
257
+ threadId,
258
+ clientContext,
259
+ data: {},
260
+ });
261
+ this.enhancedDebug(`✅ Like sent via MQTT!`);
262
+ return result;
263
+ }
264
+ /**
265
+ * Send location via MQTT (reworked)
266
+ *
267
+ * Now:
268
+ * - Tries to publish a Story with a Location sticker (preferred; matches APK behavior)
269
+ * - Shares that Story to the thread (reel_share / media_share)
270
+ * - If any step fails, falls back to sending a link to /explore/locations/{placeId}/
271
+ *
272
+ * venue shape expected:
273
+ * { id, name, address, lat, lng, facebook_places_id, external_source }
274
+ */
275
+ async sendLocation({ threadId, clientContext, venue, text = '' }) {
276
+ this.enhancedDebug(`Attempting to send location to ${threadId}. Venue: ${venue ? JSON.stringify(venue) : 'none'}`);
277
+ // Basic validation - need at least an id (or facebook_places_id)
278
+ const hasCoords = venue && typeof venue.lat === 'number' && typeof venue.lng === 'number';
279
+ const hasId = venue && (venue.facebook_places_id || venue.id);
280
+ // prefer facebook_places_id if present
281
+ const placeId = venue && (venue.facebook_places_id || venue.id);
282
+ // create sticker structure (format used by many reverse-engineered clients)
283
+ const sticker = this.createLocationStickerFromVenue(venue);
284
+ // If we have an ig client capable of publishing stories, attempt the sticker flow.
285
+ const ig = this.realtimeClient && this.realtimeClient.ig;
286
+ if (ig && typeof ig.publish === 'object' && typeof ig.publish.story === 'function') {
287
+ try {
288
+ // Use a tiny placeholder image if caller didn't provide one (1x1 PNG)
289
+ const SINGLE_PIXEL_PNG_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=";
290
+ const photoBuffer = Buffer.from(SINGLE_PIXEL_PNG_BASE64, 'base64');
291
+ this.enhancedDebug(`Publishing story with location sticker (venue id: ${placeId})...`);
292
+ // Build publish params. Many clients accept `file` and `stickers` array like this.
293
+ const publishParams = {
294
+ file: photoBuffer,
295
+ stickers: [sticker],
296
+ // optional: caption/text not always supported on story publish in the same way; keep minimal
297
+ };
298
+ const publishResult = await ig.publish.story(publishParams);
299
+ this.enhancedDebug(`Story publish result: ${publishResult ? JSON.stringify(publishResult).slice(0, 400) : 'no result'}`);
300
+ // Try to resolve story media id
301
+ let storyId = null;
302
+ if (publishResult) {
303
+ // common fields returned by private clients
304
+ storyId = publishResult.media && (publishResult.media.pk || publishResult.media.id || publishResult.media_id) ||
305
+ publishResult.item_id || publishResult.upload_id || publishResult.media_id;
306
+ }
307
+ // If we didn't get a story id, try common fallback fields
308
+ if (!storyId && publishResult && publishResult.params && publishResult.params.upload_id) {
309
+ storyId = publishResult.params.upload_id;
310
+ }
311
+ if (!storyId) {
312
+ // If publish succeeded but no usable id found, still attempt best-effort: some clients return a "media" object later on pubsub
313
+ this.enhancedDebug(`Could not determine story id from publish result; continuing to fallback to link/share attempt.`);
314
+ throw new Error('Could not determine story id from publish result.');
315
+ }
316
+ // Now share the story to the thread (reel_share/media_share)
317
+ // Use the existing helper sendUserStory if available (it uses itemType: 'reel_share')
318
+ this.enhancedDebug(`Sharing published story ${storyId} to thread ${threadId}...`);
319
+ try {
320
+ const shareResult = await this.sendUserStory({
321
+ text: text || '',
322
+ storyId: storyId,
323
+ threadId,
324
+ clientContext: clientContext || (0, uuid_1.v4)(),
325
+ });
326
+ this.enhancedDebug(`✅ Location story shared to thread via MQTT! (storyId=${storyId})`);
327
+ return shareResult;
328
+ }
329
+ catch (shareErr) {
330
+ // If sharing via MQTT fails, try a fallback: some clients expose direct send helper
331
+ this.enhancedDebug(`Sharing story to thread failed: ${shareErr && shareErr.message ? shareErr.message : String(shareErr)}`);
332
+ // fall through to fallback link below
333
+ throw shareErr;
334
+ }
335
+ }
336
+ catch (err) {
337
+ this.enhancedDebug(`Story-with-sticker attempt failed: ${err && err.message ? err.message : String(err)} - falling back to link`);
338
+ // fallthrough to fallback block below
339
+ }
340
+ }
341
+ else {
342
+ this.enhancedDebug(`ig.publish.story not available on realtimeClient.ig — will use fallback link if possible.`);
343
+ }
344
+ // Fallback: send as a link to the location explore page (guaranteed to render in DM)
345
+ if (hasId) {
346
+ const link = `https://www.instagram.com/explore/locations/${placeId}/`;
347
+ this.enhancedDebug(`Sending location fallback link: ${link}`);
348
+ try {
349
+ const fallback = await this.sendItem({
350
+ itemType: 'link',
351
+ threadId,
352
+ clientContext: clientContext || (0, uuid_1.v4)(),
353
+ data: {
354
+ link_text: text || (venue && venue.name) || 'Location',
355
+ link_urls: [link],
356
+ },
357
+ });
358
+ this.enhancedDebug(`✅ Location fallback link sent via MQTT!`);
359
+ return fallback;
360
+ }
361
+ catch (err) {
362
+ this.enhancedDebug(`Fallback link send failed: ${err && err.message ? err.message : String(err)}`);
363
+ throw err;
364
+ }
365
+ }
366
+ // If we don't have any usable info, throw an error
367
+ throw new Error('sendLocation requires a venue object with at least id (or facebook_places_id).');
368
+ }
369
+ /**
370
+ * Helper that returns a "location sticker" object compatible with many reverse-engineered
371
+ * clients / the publish.story helper. This mirrors the "LocationStickerClientModel" semantics.
372
+ *
373
+ * Format produced:
374
+ * {
375
+ * type: 'location',
376
+ * location_id: '12345',
377
+ * location: { lat, lng, name, address, external_source, facebook_places_id },
378
+ * x: 0.5,
379
+ * y: 0.5,
380
+ * width: 0.7,
381
+ * height: 0.15,
382
+ * rotation: 0,
383
+ * is_pinned: false
384
+ * }
385
+ */
386
+ createLocationStickerFromVenue(venue) {
387
+ // Defensive defaults
388
+ if (!venue) {
389
+ throw new Error('venue required to create location sticker');
390
+ }
391
+ const placeId = venue.facebook_places_id || String(venue.id || '');
392
+ const lat = (typeof venue.lat === 'number') ? venue.lat : (venue.location && venue.location.lat) || null;
393
+ const lng = (typeof venue.lng === 'number') ? venue.lng : (venue.location && venue.location.lng) || null;
394
+ const locationObj = {
395
+ lat: lat,
396
+ lng: lng,
397
+ name: venue.name || '',
398
+ address: venue.address || '',
399
+ external_source: venue.external_source || 'facebook_places',
400
+ facebook_places_id: placeId || '',
401
+ };
402
+ // Sticker appearance / position defaults - caller may tweak later if needed
403
+ const sticker = {
404
+ type: 'location',
405
+ // some clients expect locationId, some expect venue_id or location_id
406
+ locationId: placeId,
407
+ venue_id: placeId,
408
+ location: locationObj,
409
+ x: 0.5,
410
+ y: 0.5,
411
+ width: 0.7,
412
+ height: 0.15,
413
+ rotation: 0,
414
+ isPinned: false,
415
+ };
416
+ return sticker;
417
+ }
418
+ /**
419
+ * Helper: search places via the Instagram client (optional).
420
+ * If your realtimeClient has an .ig.request helper, this will call the appropriate
421
+ * endpoint to fetch place metadata, and then call sendLocation with the full venue.
422
+ *
423
+ * This is optional — you can call sendLocation yourself with the venue object you already have.
424
+ */
425
+ async searchAndSendLocation({ threadId, query, lat, lng, clientContext }) {
426
+ const ig = this.realtimeClient && this.realtimeClient.ig;
427
+ if (!ig || !ig.request) {
428
+ throw new Error('Instagram client (ig.request) not available on realtimeClient. Provide `venue` directly to sendLocation instead.');
429
+ }
430
+ this.enhancedDebug(`Searching location: ${query} at ${lat},${lng}`);
431
+ // Example endpoint - private API endpoints vary. If your client has a helper method,
432
+ // prefer that. This tries a common private endpoint pattern.
433
+ const url = '/fbsearch/places/';
434
+ const params = {
435
+ search_media_creation: false,
436
+ rank_token: (0, uuid_1.v4)(),
437
+ query: query,
438
+ latitude: lat,
439
+ longitude: lng,
440
+ };
441
+ try {
442
+ const res = await ig.request.send({
443
+ url: url,
444
+ method: 'GET',
445
+ qs: params,
446
+ });
447
+ // Parse response - different private API clients return different shapes.
448
+ // We try to find the first usable place with id/lat/lng/name.
449
+ const places = (res && (res.places || res.items || res.results)) || [];
450
+ const place = places.find(p => p && (p.pk || p.place || p.location || p.facebook_places_id)) || places[0];
451
+ if (!place) {
452
+ throw new Error('No places found from search.');
453
+ }
454
+ // Normalize to `venue` shape our sendLocation expects
455
+ const venue = {
456
+ id: String(place.pk || (place.place && place.place.id) || place.id || place.facebook_places_id || ''),
457
+ name: place.name || (place.place && place.place.name) || '',
458
+ address: place.address || (place.place && place.place.address) || '',
459
+ lat: (place.location && (place.location.lat || place.location.latitude)) || place.lat || null,
460
+ lng: (place.location && (place.location.lng || place.location.longitude)) || place.lng || null,
461
+ facebook_places_id: place.facebook_places_id || (place.place && place.place.id) || String(place.pk || ''),
462
+ external_source: place.external_source || 'facebook_places',
463
+ };
464
+ return await this.sendLocation({ threadId, clientContext, venue });
465
+ }
466
+ catch (err) {
467
+ this.enhancedDebug(`place search/send failed: ${err && err.message ? err.message : String(err)}`);
468
+ throw err;
469
+ }
470
+ }
471
+ /**
472
+ * Send media via MQTT (media_share)
473
+ */
474
+ async sendMedia({ text, mediaId, threadId, clientContext }) {
475
+ this.enhancedDebug(`Sending media ${mediaId} to ${threadId}`);
476
+ const result = await this.sendItem({
477
+ itemType: 'media_share',
478
+ threadId,
479
+ clientContext,
480
+ data: {
481
+ text: text || '',
482
+ media_id: mediaId,
483
+ },
484
+ });
485
+ this.enhancedDebug(`✅ Media sent via MQTT!`);
486
+ return result;
487
+ }
488
+ /**
489
+ * Send profile via MQTT
490
+ */
491
+ async sendProfile({ text, userId, threadId, clientContext }) {
492
+ this.enhancedDebug(`Sending profile ${userId} to ${threadId}`);
493
+ const result = await this.sendItem({
494
+ itemType: 'profile',
495
+ threadId,
496
+ clientContext,
497
+ data: {
498
+ text: text || '',
499
+ profile_user_id: userId,
500
+ item_id: userId,
501
+ },
502
+ });
503
+ this.enhancedDebug(`✅ Profile sent via MQTT!`);
504
+ return result;
505
+ }
506
+ /**
507
+ * Send reaction via MQTT
508
+ */
509
+ async sendReaction({ itemId, reactionType, clientContext, threadId, reactionStatus, targetItemType, emoji }) {
510
+ this.enhancedDebug(`Sending ${reactionType || 'like'} reaction to message ${itemId}`);
511
+ const result = await this.sendItem({
512
+ itemType: 'reaction',
513
+ threadId,
514
+ clientContext,
515
+ data: {
516
+ item_id: itemId,
517
+ node_type: 'item',
518
+ reaction_type: reactionType || (emoji ? 'emoji' : 'like'),
519
+ reaction_status: reactionStatus || 'created',
520
+ target_item_type: targetItemType,
521
+ emoji: emoji || '',
522
+ },
523
+ });
524
+ this.enhancedDebug(`✅ Reaction sent via MQTT!`);
525
+ return result;
526
+ }
527
+ /**
528
+ * Send user story via MQTT (reel_share)
529
+ */
530
+ async sendUserStory({ text, storyId, threadId, clientContext }) {
531
+ this.enhancedDebug(`Sending story ${storyId} to ${threadId}`);
532
+ const result = await this.sendItem({
533
+ itemType: 'reel_share',
534
+ threadId,
535
+ clientContext,
536
+ data: {
537
+ text: text || '',
538
+ item_id: storyId,
539
+ media_id: storyId,
540
+ },
541
+ });
542
+ this.enhancedDebug(`✅ Story sent via MQTT!`);
543
+ return result;
544
+ }
545
+ /**
546
+ * Mark as seen via REST API (with MQTT fallback)
547
+ *
548
+ * Instagram requires the REST endpoint /api/v1/direct_v2/threads/{threadId}/items/{itemId}/seen/
549
+ * for marking messages as seen. The MQTT mark_seen action on topic 132 is not processed
550
+ * by Instagram's servers. This method uses the ig client's REST API which is accessible
551
+ * through the realtime client.
552
+ */
553
+ async markAsSeen({ threadId, itemId }) {
554
+ this.enhancedDebug(`Marking message ${itemId} as seen in thread ${threadId}`);
555
+ const ig = this.realtimeClient && this.realtimeClient.ig;
556
+ if (ig && ig.request) {
557
+ try {
558
+ const clientContext = (0, uuid_1.v4)();
559
+ const form = {
560
+ _uuid: ig.state.uuid,
561
+ device_id: ig.state.deviceId,
562
+ use_unified_inbox: true,
563
+ action: 'mark_seen',
564
+ thread_id: threadId,
565
+ item_id: itemId,
566
+ client_context: clientContext,
567
+ mutation_token: clientContext,
568
+ };
569
+ const response = await ig.request.send({
570
+ url: `/api/v1/direct_v2/threads/${threadId}/items/${itemId}/seen/`,
571
+ method: 'POST',
572
+ form: form,
573
+ });
574
+ const body = response.body || response.data || response;
575
+ const parsed = typeof body === 'string' ? JSON.parse(body) : body;
576
+ if (parsed && parsed.status === 'ok') {
577
+ this.enhancedDebug(`✅ Message marked as seen via REST API! Status: ok`);
578
+ return parsed;
579
+ }
580
+ this.enhancedDebug(`REST mark_seen response: ${JSON.stringify(parsed).slice(0, 300)}`);
581
+ return parsed;
582
+ }
583
+ catch (restErr) {
584
+ this.enhancedDebug(`REST mark_seen failed: ${restErr && restErr.message ? restErr.message : String(restErr)}, falling back to MQTT`);
585
+ }
586
+ }
587
+ else {
588
+ this.enhancedDebug(`ig.request not available, using MQTT fallback for mark_seen`);
589
+ }
590
+ const result = await this.sendCommand({
591
+ action: 'mark_seen',
592
+ threadId,
593
+ data: {
594
+ item_id: itemId,
595
+ },
596
+ });
597
+ this.enhancedDebug(`⚠️ Message mark_seen sent via MQTT (fallback - may not be processed by Instagram)`);
598
+ return result;
599
+ }
600
+ /**
601
+ * Indicate activity (typing) via MQTT (activity_status)
602
+ */
603
+ async indicateActivity({ threadId, isActive, clientContext }) {
604
+ const active = typeof isActive === 'undefined' ? true : isActive;
605
+ this.enhancedDebug(`Indicating ${active ? 'typing' : 'stopped'} in thread ${threadId}`);
606
+ const result = await this.sendCommand({
607
+ action: 'indicate_activity',
608
+ threadId,
609
+ clientContext: clientContext || (0, uuid_1.v4)(),
610
+ data: {
611
+ activity_status: active ? '1' : '0',
612
+ },
613
+ });
614
+ this.enhancedDebug(`✅ Activity indicator sent via MQTT!`);
615
+ return result;
616
+ }
617
+ /**
618
+ * Delete message via MQTT
619
+ */
620
+ async deleteMessage(threadId, itemId) {
621
+ this.enhancedDebug(`Deleting message ${itemId} from thread ${threadId}`);
622
+ const result = await this.sendCommand({
623
+ action: 'delete_item',
624
+ threadId,
625
+ clientContext: (0, uuid_1.v4)(),
626
+ data: {
627
+ item_id: itemId,
628
+ },
629
+ });
630
+ this.enhancedDebug(`✅ Message deleted via MQTT!`);
631
+ return result;
632
+ }
633
+ /**
634
+ * Edit message via MQTT
635
+ */
636
+ async editMessage(threadId, itemId, newText) {
637
+ this.enhancedDebug(`Editing message ${itemId}: "${newText}"`);
638
+ const result = await this.sendCommand({
639
+ action: 'edit_item',
640
+ threadId,
641
+ clientContext: (0, uuid_1.v4)(),
642
+ data: {
643
+ item_id: itemId,
644
+ text: newText,
645
+ },
646
+ });
647
+ this.enhancedDebug(`✅ Message edited via MQTT!`);
648
+ return result;
649
+ }
650
+ /**
651
+ * Reply to message via MQTT (Quote Reply)
652
+ */
653
+ async replyToMessage(threadId, messageId, replyText) {
654
+ this.enhancedDebug(`Replying to ${messageId} in thread ${threadId}: "${replyText}"`);
655
+ const result = await this.sendItem({
656
+ itemType: 'text',
657
+ threadId,
658
+ clientContext: (0, uuid_1.v4)(),
659
+ data: {
660
+ text: replyText,
661
+ replied_to_item_id: messageId,
662
+ },
663
+ });
664
+ this.enhancedDebug(`✅ Reply sent via MQTT!`);
665
+ return result;
666
+ }
667
+ /**
668
+ * Add member to thread via MQTT
669
+ */
670
+ async addMemberToThread(threadId, userId) {
671
+ this.enhancedDebug(`Adding user ${userId} to thread ${threadId}`);
672
+ const result = await this.sendCommand({
673
+ action: 'add_users',
674
+ threadId,
675
+ clientContext: (0, uuid_1.v4)(),
676
+ data: {
677
+ user_ids: Array.isArray(userId) ? userId : [userId],
678
+ },
679
+ });
680
+ this.enhancedDebug(`✅ Member added to thread via MQTT!`);
681
+ return result;
682
+ }
683
+ /**
684
+ * Remove member from thread via MQTT
685
+ */
686
+ async removeMemberFromThread(threadId, userId) {
687
+ this.enhancedDebug(`Removing user ${userId} from thread ${threadId}`);
688
+ const result = await this.sendCommand({
689
+ action: 'remove_users',
690
+ threadId,
691
+ clientContext: (0, uuid_1.v4)(),
692
+ data: {
693
+ user_ids: Array.isArray(userId) ? userId : [userId],
694
+ },
695
+ });
696
+ this.enhancedDebug(`✅ Member removed from thread via MQTT!`);
697
+ return result;
698
+ }
699
+ /**
700
+ * Leave thread via MQTT
701
+ */
702
+ async leaveThread(threadId) {
703
+ this.enhancedDebug(`Leaving thread ${threadId}`);
704
+ const result = await this.sendCommand({
705
+ action: 'leave',
706
+ threadId,
707
+ clientContext: (0, uuid_1.v4)(),
708
+ data: {},
709
+ });
710
+ this.enhancedDebug(`✅ Left thread via MQTT!`);
711
+ return result;
712
+ }
713
+ /**
714
+ * Mute thread via MQTT
715
+ */
716
+ async muteThread(threadId, muteUntil = null) {
717
+ this.enhancedDebug(`Muting thread ${threadId}`);
718
+ const result = await this.sendCommand({
719
+ action: 'mute',
720
+ threadId,
721
+ clientContext: (0, uuid_1.v4)(),
722
+ data: {
723
+ mute_until: muteUntil,
724
+ },
725
+ });
726
+ this.enhancedDebug(`✅ Thread muted via MQTT!`);
727
+ return result;
728
+ }
729
+ /**
730
+ * Unmute thread via MQTT
731
+ */
732
+ async unmuteThread(threadId) {
733
+ this.enhancedDebug(`Unmuting thread ${threadId}`);
734
+ const result = await this.sendCommand({
735
+ action: 'unmute',
736
+ threadId,
737
+ clientContext: (0, uuid_1.v4)(),
738
+ data: {},
739
+ });
740
+ this.enhancedDebug(`✅ Thread unmuted via MQTT!`);
741
+ return result;
742
+ }
743
+ /**
744
+ * Update thread title via MQTT
745
+ */
746
+ async updateThreadTitle(threadId, title) {
747
+ this.enhancedDebug(`Updating thread ${threadId} title to: "${title}"`);
748
+ const result = await this.sendCommand({
749
+ action: 'update_title',
750
+ threadId,
751
+ clientContext: (0, uuid_1.v4)(),
752
+ data: {
753
+ title: title,
754
+ },
755
+ });
756
+ this.enhancedDebug(`✅ Thread title updated via MQTT!`);
757
+ return result;
758
+ }
759
+ /**
760
+ * Send link via MQTT
761
+ */
762
+ async sendLink({ link, text, threadId, clientContext }) {
763
+ this.enhancedDebug(`Sending link ${link} to ${threadId}`);
764
+ const result = await this.sendItem({
765
+ itemType: 'link',
766
+ threadId,
767
+ clientContext,
768
+ data: {
769
+ link_text: text || '',
770
+ // use array (not JSON string) to match instagram_mqtt expectations
771
+ link_urls: [link],
772
+ },
773
+ });
774
+ this.enhancedDebug(`✅ Link sent via MQTT!`);
775
+ return result;
776
+ }
777
+ /**
778
+ * Send animated media (GIF/sticker) via MQTT
779
+ */
780
+ async sendAnimatedMedia({ id, isSticker, threadId, clientContext }) {
781
+ this.enhancedDebug(`Sending animated media ${id} to ${threadId}`);
782
+ const result = await this.sendItem({
783
+ itemType: 'animated_media',
784
+ threadId,
785
+ clientContext,
786
+ data: {
787
+ id: id,
788
+ is_sticker: isSticker || false,
789
+ },
790
+ });
791
+ this.enhancedDebug(`✅ Animated media sent via MQTT!`);
792
+ return result;
793
+ }
794
+ /**
795
+ * Send voice message via MQTT (after upload)
796
+ */
797
+ async sendVoice({ uploadId, waveform, waveformSamplingFrequencyHz, threadId, clientContext }) {
798
+ this.enhancedDebug(`Sending voice ${uploadId} to ${threadId}`);
799
+ const result = await this.sendItem({
800
+ itemType: 'voice_media',
801
+ threadId,
802
+ clientContext,
803
+ data: {
804
+ upload_id: uploadId,
805
+ waveform: waveform,
806
+ waveform_sampling_frequency_hz: waveformSamplingFrequencyHz || 10,
807
+ },
808
+ });
809
+ this.enhancedDebug(`✅ Voice sent via MQTT!`);
810
+ return result;
811
+ }
812
+ /**
813
+ * Send photo via Realtime (Upload + Broadcast)
814
+ * Note: depends on realtimeClient.ig.request for uploading
815
+ */
816
+ async sendPhotoViaRealtime({ photoBuffer, threadId, caption = '', mimeType = 'image/jpeg', clientContext }) {
817
+ this.enhancedDebug(`Sending photo to thread ${threadId} via Realtime`);
818
+ try {
819
+ if (!photoBuffer || !Buffer.isBuffer(photoBuffer) || photoBuffer.length === 0) {
820
+ throw new Error('photoBuffer must be a non-empty Buffer');
821
+ }
822
+ if (!threadId) {
823
+ throw new Error('threadId is required');
824
+ }
825
+ const ig = this.realtimeClient.ig;
826
+ if (!ig || !ig.request) {
827
+ throw new Error('Instagram client not available. Make sure you are logged in.');
828
+ }
829
+ this.enhancedDebug(`Step 1: Uploading photo (${photoBuffer.length} bytes)...`);
830
+ const uploadId = Date.now().toString();
831
+ const objectName = `${(0, uuid_1.v4)()}.${mimeType === 'image/png' ? 'png' : 'jpg'}`;
832
+ const isJpeg = mimeType === 'image/jpeg' || mimeType === 'image/jpg';
833
+ const compression = isJpeg
834
+ ? '{"lib_name":"moz","lib_version":"3.1.m","quality":"80"}'
835
+ : '{"lib_name":"png","lib_version":"1.0","quality":"100"}';
836
+ const ruploadParams = {
837
+ upload_id: uploadId,
838
+ media_type: 1,
839
+ image_compression: compression,
840
+ xsharing_user_ids: JSON.stringify([]),
841
+ is_clips_media: false,
842
+ };
843
+ const uploadHeaders = {
844
+ 'X-Instagram-Rupload-Params': JSON.stringify(ruploadParams),
845
+ 'Content-Type': mimeType,
846
+ 'X_FB_PHOTO_WATERFALL_ID': (0, uuid_1.v4)(),
847
+ 'X-Entity-Type': mimeType,
848
+ 'X-Entity-Length': String(photoBuffer.length),
849
+ 'Content-Length': String(photoBuffer.length),
850
+ };
851
+ const uploadUrl = `/rupload_igphoto/${objectName}`;
852
+ let serverUploadId = uploadId;
853
+ try {
854
+ const uploadResponse = await ig.request.send({
855
+ url: uploadUrl,
856
+ method: 'POST',
857
+ headers: uploadHeaders,
858
+ body: photoBuffer,
859
+ });
860
+ if (uploadResponse && typeof uploadResponse === 'object' && uploadResponse.upload_id) {
861
+ serverUploadId = uploadResponse.upload_id;
862
+ }
863
+ this.enhancedDebug(`✅ Photo uploaded! upload_id: ${serverUploadId}`);
864
+ }
865
+ catch (uploadErr) {
866
+ this.enhancedDebug(`Upload error: ${uploadErr && uploadErr.message ? uploadErr.message : String(uploadErr)}`);
867
+ throw new Error(`Photo upload failed: ${uploadErr && uploadErr.message ? uploadErr.message : String(uploadErr)}`);
868
+ }
869
+ this.enhancedDebug(`Step 2: Broadcasting photo to thread ${threadId}...`);
870
+ const broadcastForm = {
871
+ upload_id: serverUploadId,
872
+ action: 'send_item',
873
+ thread_ids: JSON.stringify([String(threadId)]),
874
+ };
875
+ if (caption) {
876
+ broadcastForm.caption = caption;
877
+ }
878
+ try {
879
+ const broadcastResponse = await ig.request.send({
880
+ url: '/direct_v2/threads/broadcast/upload_photo/',
881
+ method: 'POST',
882
+ form: broadcastForm,
883
+ });
884
+ this.enhancedDebug(`✅ Photo sent successfully to thread ${threadId}!`);
885
+ return broadcastResponse;
886
+ }
887
+ catch (broadcastErr) {
888
+ this.enhancedDebug(`Broadcast error: ${broadcastErr && broadcastErr.message ? broadcastErr.message : String(broadcastErr)}`);
889
+ throw new Error(`Photo broadcast failed: ${broadcastErr && broadcastErr.message ? broadcastErr.message : String(broadcastErr)}`);
890
+ }
891
+ }
892
+ catch (err) {
893
+ this.enhancedDebug(`sendPhotoViaRealtime failed: ${err && err.message ? err.message : String(err)}`);
894
+ throw err;
895
+ }
896
+ }
897
+ /**
898
+ * Alias for sendPhotoViaRealtime
899
+ */
900
+ async sendPhoto(options) {
901
+ return this.sendPhotoViaRealtime(options);
902
+ }
903
+ /**
904
+ * Send video via Realtime (Upload + Broadcast)
905
+ * Note: depends on realtimeClient.ig.request for uploading
906
+ */
907
+ async sendVideoViaRealtime({ videoBuffer, threadId, caption = '', duration = 0, width = 720, height = 1280, clientContext }) {
908
+ this.enhancedDebug(`Sending video to thread ${threadId} via Realtime`);
909
+ try {
910
+ if (!videoBuffer || !Buffer.isBuffer(videoBuffer) || videoBuffer.length === 0) {
911
+ throw new Error('videoBuffer must be a non-empty Buffer');
912
+ }
913
+ if (!threadId) {
914
+ throw new Error('threadId is required');
915
+ }
916
+ const ig = this.realtimeClient.ig;
917
+ if (!ig || !ig.request) {
918
+ throw new Error('Instagram client not available. Make sure you are logged in.');
919
+ }
920
+ this.enhancedDebug(`Step 1: Uploading video (${videoBuffer.length} bytes)...`);
921
+ const uploadId = Date.now().toString();
922
+ const objectName = `${(0, uuid_1.v4)()}.mp4`;
923
+ const ruploadParams = {
924
+ upload_id: uploadId,
925
+ media_type: 2,
926
+ xsharing_user_ids: JSON.stringify([]),
927
+ upload_media_duration_ms: Math.round(duration * 1000),
928
+ upload_media_width: width,
929
+ upload_media_height: height,
930
+ };
931
+ const uploadHeaders = {
932
+ 'X-Instagram-Rupload-Params': JSON.stringify(ruploadParams),
933
+ 'Content-Type': 'video/mp4',
934
+ 'X_FB_VIDEO_WATERFALL_ID': (0, uuid_1.v4)(),
935
+ 'X-Entity-Type': 'video/mp4',
936
+ 'X-Entity-Length': String(videoBuffer.length),
937
+ 'Content-Length': String(videoBuffer.length),
938
+ 'Offset': '0',
939
+ };
940
+ const uploadUrl = `/rupload_igvideo/${objectName}`;
941
+ let serverUploadId = uploadId;
942
+ try {
943
+ const uploadResponse = await ig.request.send({
944
+ url: uploadUrl,
945
+ method: 'POST',
946
+ headers: uploadHeaders,
947
+ body: videoBuffer,
948
+ });
949
+ if (uploadResponse && typeof uploadResponse === 'object' && uploadResponse.upload_id) {
950
+ serverUploadId = uploadResponse.upload_id;
951
+ }
952
+ this.enhancedDebug(`✅ Video uploaded! upload_id: ${serverUploadId}`);
953
+ }
954
+ catch (uploadErr) {
955
+ this.enhancedDebug(`Video upload error: ${uploadErr && uploadErr.message ? uploadErr.message : String(uploadErr)}`);
956
+ throw new Error(`Video upload failed: ${uploadErr && uploadErr.message ? uploadErr.message : String(uploadErr)}`);
957
+ }
958
+ this.enhancedDebug(`Step 2: Broadcasting video to thread ${threadId}...`);
959
+ const broadcastForm = {
960
+ upload_id: serverUploadId,
961
+ action: 'send_item',
962
+ thread_ids: JSON.stringify([String(threadId)]),
963
+ video_result: '',
964
+ };
965
+ if (caption) {
966
+ broadcastForm.caption = caption;
967
+ }
968
+ try {
969
+ const broadcastResponse = await ig.request.send({
970
+ url: '/direct_v2/threads/broadcast/upload_video/',
971
+ method: 'POST',
972
+ form: broadcastForm,
973
+ });
974
+ this.enhancedDebug(`✅ Video sent successfully to thread ${threadId}!`);
975
+ return broadcastResponse;
976
+ }
977
+ catch (broadcastErr) {
978
+ this.enhancedDebug(`Video broadcast error: ${broadcastErr && broadcastErr.message ? broadcastErr.message : String(broadcastErr)}`);
979
+ throw new Error(`Video broadcast failed: ${broadcastErr && broadcastErr.message ? broadcastErr.message : String(broadcastErr)}`);
980
+ }
981
+ }
982
+ catch (err) {
983
+ this.enhancedDebug(`sendVideoViaRealtime failed: ${err && err.message ? err.message : String(err)}`);
984
+ throw err;
985
+ }
986
+ }
987
+ /**
988
+ * Alias for sendVideoViaRealtime
989
+ */
990
+ async sendVideo(options) {
991
+ return this.sendVideoViaRealtime(options);
992
+ }
993
+ /**
994
+ * Approve pending thread via MQTT
995
+ */
996
+ async approveThread(threadId) {
997
+ this.enhancedDebug(`Approving thread ${threadId}`);
998
+ const result = await this.sendCommand({
999
+ action: 'approve',
1000
+ threadId,
1001
+ clientContext: (0, uuid_1.v4)(),
1002
+ data: {},
1003
+ });
1004
+ this.enhancedDebug(`✅ Thread approved via MQTT!`);
1005
+ return result;
1006
+ }
1007
+ /**
1008
+ * Decline pending thread via MQTT
1009
+ */
1010
+ async declineThread(threadId) {
1011
+ this.enhancedDebug(`Declining thread ${threadId}`);
1012
+ const result = await this.sendCommand({
1013
+ action: 'decline',
1014
+ threadId,
1015
+ clientContext: (0, uuid_1.v4)(),
1016
+ data: {},
1017
+ });
1018
+ this.enhancedDebug(`✅ Thread declined via MQTT!`);
1019
+ return result;
1020
+ }
1021
+ /**
1022
+ * Block user in thread via MQTT
1023
+ */
1024
+ async blockUserInThread(threadId, userId) {
1025
+ this.enhancedDebug(`Blocking user ${userId} in thread ${threadId}`);
1026
+ const result = await this.sendCommand({
1027
+ action: 'block',
1028
+ threadId,
1029
+ clientContext: (0, uuid_1.v4)(),
1030
+ data: {
1031
+ user_id: userId,
1032
+ },
1033
+ });
1034
+ this.enhancedDebug(`✅ User blocked in thread via MQTT!`);
1035
+ return result;
1036
+ }
1037
+ /**
1038
+ * Report thread via MQTT
1039
+ */
1040
+ async reportThread(threadId, reason) {
1041
+ this.enhancedDebug(`Reporting thread ${threadId}`);
1042
+ const result = await this.sendCommand({
1043
+ action: 'report',
1044
+ threadId,
1045
+ clientContext: (0, uuid_1.v4)(),
1046
+ data: {
1047
+ reason: reason || 'spam',
1048
+ },
1049
+ });
1050
+ this.enhancedDebug(`✅ Thread reported via MQTT!`);
1051
+ return result;
1052
+ }
1053
+ /**
1054
+ * Remove reaction via MQTT
1055
+ */
1056
+ async removeReaction({ itemId, threadId, clientContext }) {
1057
+ this.enhancedDebug(`Removing reaction from message ${itemId}`);
1058
+ const result = await this.sendItem({
1059
+ itemType: 'reaction',
1060
+ threadId,
1061
+ clientContext,
1062
+ data: {
1063
+ item_id: itemId,
1064
+ node_type: 'item',
1065
+ reaction_type: 'like',
1066
+ reaction_status: 'deleted',
1067
+ },
1068
+ });
1069
+ this.enhancedDebug(`✅ Reaction removed via MQTT!`);
1070
+ return result;
1071
+ }
1072
+ /**
1073
+ * Send disappearing photo via MQTT (broadcast only - requires pre-uploaded media)
1074
+ */
1075
+ async sendDisappearingPhoto({ uploadId, threadId, viewMode = 'once', clientContext }) {
1076
+ this.enhancedDebug(`Sending disappearing photo to ${threadId}`);
1077
+ const ephemeralViewMode = (viewMode === 'replayable') ? 2 : 1;
1078
+ const result = await this.sendItem({
1079
+ itemType: 'raven_media',
1080
+ threadId,
1081
+ clientContext,
1082
+ data: {
1083
+ upload_id: uploadId,
1084
+ view_mode: viewMode,
1085
+ ephemeral_media_view_mode: ephemeralViewMode,
1086
+ allow_full_aspect_ratio: true,
1087
+ send_attribution: 'direct_composer',
1088
+ },
1089
+ });
1090
+ this.enhancedDebug(`✅ Disappearing photo sent via MQTT!`);
1091
+ return result;
1092
+ }
1093
+ /**
1094
+ * Send disappearing video via MQTT (broadcast only - requires pre-uploaded media)
1095
+ */
1096
+ async sendDisappearingVideo({ uploadId, threadId, viewMode = 'once', clientContext }) {
1097
+ this.enhancedDebug(`Sending disappearing video to ${threadId}`);
1098
+ const ephemeralViewMode = (viewMode === 'replayable') ? 2 : 1;
1099
+ const result = await this.sendItem({
1100
+ itemType: 'raven_media',
1101
+ threadId,
1102
+ clientContext,
1103
+ data: {
1104
+ upload_id: uploadId,
1105
+ view_mode: viewMode,
1106
+ ephemeral_media_view_mode: ephemeralViewMode,
1107
+ allow_full_aspect_ratio: true,
1108
+ media_type: 2,
1109
+ send_attribution: 'direct_composer',
1110
+ },
1111
+ });
1112
+ this.enhancedDebug(`✅ Disappearing video sent via MQTT!`);
1113
+ return result;
1114
+ }
1115
+ /**
1116
+ * Send raven (view-once) photo - COMPLETE flow:
1117
+ * 1. Upload photo to rupload.facebook.com/messenger_image/ (required for raven)
1118
+ * 2. Broadcast via REST to /direct_v2/threads/broadcast/raven_attachment/
1119
+ *
1120
+ * @param {Object} options
1121
+ * @param {Buffer} options.photoBuffer - The photo as a Buffer
1122
+ * @param {string} options.threadId - Thread ID to send to
1123
+ * @param {string} [options.viewMode='once'] - 'once' or 'replayable'
1124
+ * @param {string} [options.mimeType='image/jpeg'] - MIME type of the image
1125
+ * @returns {Promise<Object>} - REST broadcast response
1126
+ */
1127
+ async sendRavenPhoto({ photoBuffer, threadId, viewMode = 'once', mimeType = 'image/jpeg' }) {
1128
+ var _a, _b, _c, _d;
1129
+ this.enhancedDebug(`Sending raven photo to thread ${threadId} (viewMode: ${viewMode})`);
1130
+ try {
1131
+ if (!photoBuffer || !Buffer.isBuffer(photoBuffer) || photoBuffer.length === 0) {
1132
+ throw new Error('photoBuffer must be a non-empty Buffer');
1133
+ }
1134
+ if (!threadId) {
1135
+ throw new Error('threadId is required');
1136
+ }
1137
+ const ig = this.realtimeClient.ig;
1138
+ if (!ig || !ig.request) {
1139
+ throw new Error('Instagram client not available. Make sure you are logged in.');
1140
+ }
1141
+ const axios = require('axios');
1142
+ this.enhancedDebug(`Step 1: Uploading raven photo to messenger_image (${photoBuffer.length} bytes)...`);
1143
+ const uploadId = Date.now().toString();
1144
+ const randomSuffix = Math.floor(Math.random() * (9999999999 - 1000000000) + 1000000000);
1145
+ const name = `${uploadId}_0_${randomSuffix}`;
1146
+ const waterfallId = (0, uuid_1.v4)();
1147
+ const ruploadParams = {
1148
+ retry_context: '{"num_step_auto_retry":0,"num_reupload":0,"num_step_manual_retry":0}',
1149
+ media_type: '1',
1150
+ upload_id: uploadId,
1151
+ image_compression: '{"lib_name":"moz","lib_version":"3.1.m","quality":"95"}',
1152
+ xsharing_user_ids: JSON.stringify([]),
1153
+ direct_v2: '1',
1154
+ is_optimistic_upload: 'false',
1155
+ };
1156
+ const defaultHeaders = ig.request.getDefaultHeaders();
1157
+ const messengerUploadHeaders = {
1158
+ ...defaultHeaders,
1159
+ 'X_FB_PHOTO_WATERFALL_ID': waterfallId,
1160
+ 'X-Entity-Type': mimeType,
1161
+ 'Offset': '0',
1162
+ 'X-Instagram-Rupload-Params': JSON.stringify(ruploadParams),
1163
+ 'X-Entity-Name': name,
1164
+ 'X-Entity-Length': String(photoBuffer.length),
1165
+ 'Content-Type': 'application/octet-stream',
1166
+ 'Content-Length': String(photoBuffer.length),
1167
+ 'ephemeral_media_view_mode': viewMode === 'replayable' ? '1' : '0',
1168
+ 'ig_raven_metadata': '{}',
1169
+ 'image_type': 'FILE_ATTACHMENT',
1170
+ 'Host': 'rupload.facebook.com',
1171
+ };
1172
+ let serverUploadId = uploadId;
1173
+ let attachmentFbid = null;
1174
+ try {
1175
+ const uploadResp = await axios({
1176
+ url: `https://rupload.facebook.com/messenger_image/${name}`,
1177
+ method: 'POST',
1178
+ headers: messengerUploadHeaders,
1179
+ data: photoBuffer,
1180
+ maxBodyLength: Infinity,
1181
+ maxContentLength: Infinity,
1182
+ transformRequest: [(d) => d],
1183
+ });
1184
+ const uploadParsed = uploadResp.data;
1185
+ serverUploadId = (uploadParsed.upload_id || uploadId).toString();
1186
+ attachmentFbid = uploadParsed.media_id
1187
+ || (uploadParsed.media && uploadParsed.media.pk)
1188
+ || null;
1189
+ this.enhancedDebug(`Raven photo uploaded! upload_id: ${serverUploadId}, media_id: ${attachmentFbid}`);
1190
+ }
1191
+ catch (uploadErr) {
1192
+ const msg = uploadErr && uploadErr.message ? uploadErr.message : String(uploadErr);
1193
+ this.enhancedDebug(`Raven photo upload error: ${msg}`);
1194
+ throw new Error(`Raven photo upload failed: ${msg}`);
1195
+ }
1196
+ this.enhancedDebug(`Step 2: Broadcasting via REST to raven_attachment/...`);
1197
+ const clientContext = BigInt(Math.floor(Math.random() * 2 ** 62)).toString();
1198
+ const compositionId = (0, uuid_1.v4)();
1199
+ const cameraSessionId = (0, uuid_1.v4)();
1200
+ const now = Math.floor(Date.now() / 1000);
1201
+ const form = {
1202
+ allow_multi_configures: '1',
1203
+ recipient_users: '[]',
1204
+ view_mode: viewMode,
1205
+ is_shh_mode: '0',
1206
+ camera_entry_point: '3',
1207
+ thread_ids: JSON.stringify([String(threadId)]),
1208
+ reshare_mode: 'allow_reshare',
1209
+ original_media_type: '1',
1210
+ send_attribution: 'direct_thread_camera',
1211
+ client_context: clientContext,
1212
+ camera_session_id: cameraSessionId,
1213
+ include_e2ee_mentioned_user_list: '1',
1214
+ hide_from_profile_grid: 'false',
1215
+ scene_capture_type: '',
1216
+ timezone_offset: String(new Date().getTimezoneOffset() * -60),
1217
+ client_shared_at: String(now),
1218
+ configure_mode: '2',
1219
+ source_type: '4',
1220
+ camera_position: 'unknown',
1221
+ _uid: String(ig.state.cookieUserId || ig.state.igUserId),
1222
+ device_id: ig.state.deviceId,
1223
+ composition_id: compositionId,
1224
+ mutation_token: clientContext,
1225
+ _uuid: ig.state.uuid,
1226
+ creation_tool_info: '[]',
1227
+ creation_surface: 'camera',
1228
+ capture_type: 'normal',
1229
+ audience: 'default',
1230
+ upload_id: serverUploadId,
1231
+ client_timestamp: String(now),
1232
+ sampled: 'true',
1233
+ media_transformation_info: JSON.stringify({
1234
+ width: '720', height: '1280',
1235
+ x_transform: '0', y_transform: '0',
1236
+ zoom: '1.0', rotation: '0.0', background_coverage: '0.0',
1237
+ }),
1238
+ edits: JSON.stringify({ filter_type: 0, filter_strength: 0.5, crop_original_size: [720.0, 1280.0] }),
1239
+ extra: JSON.stringify({ source_width: 720, source_height: 1280 }),
1240
+ device: JSON.stringify({
1241
+ manufacturer: ((_a = ig.state.devicePayload) === null || _a === void 0 ? void 0 : _a.manufacturer) || 'samsung',
1242
+ model: ((_b = ig.state.devicePayload) === null || _b === void 0 ? void 0 : _b.model) || 'SM-S938B',
1243
+ android_version: ((_c = ig.state.devicePayload) === null || _c === void 0 ? void 0 : _c.android_version) || 35,
1244
+ android_release: ((_d = ig.state.devicePayload) === null || _d === void 0 ? void 0 : _d.android_release) || '15',
1245
+ }),
1246
+ };
1247
+ if (attachmentFbid) {
1248
+ form.attachment_fbid = String(attachmentFbid);
1249
+ }
1250
+ const payloadForm = (ig.request && typeof ig.request.sign === 'function')
1251
+ ? ig.request.sign(form)
1252
+ : form;
1253
+ const result = await ig.request.send({
1254
+ url: '/api/v1/direct_v2/threads/broadcast/raven_attachment/',
1255
+ method: 'POST',
1256
+ form: payloadForm,
1257
+ qs: { use_unified_inbox: true },
1258
+ });
1259
+ const body = result && (result.body || result.data || result);
1260
+ this.enhancedDebug(`Raven photo broadcast SUCCESS`);
1261
+ return typeof body === 'string' ? JSON.parse(body) : body;
1262
+ }
1263
+ catch (err) {
1264
+ this.enhancedDebug(`sendRavenPhoto failed: ${err && err.message ? err.message : String(err)}`);
1265
+ throw err;
1266
+ }
1267
+ }
1268
+ /**
1269
+ * Send raven photo (view once) - convenience wrapper
1270
+ */
1271
+ async sendRavenPhotoOnce(options) {
1272
+ return this.sendRavenPhoto({ ...options, viewMode: 'once' });
1273
+ }
1274
+ /**
1275
+ * Send raven photo (replayable) - convenience wrapper
1276
+ */
1277
+ async sendRavenPhotoReplayable(options) {
1278
+ return this.sendRavenPhoto({ ...options, viewMode: 'replayable' });
1279
+ }
1280
+ /**
1281
+ * Send raven (view-once) video - COMPLETE flow:
1282
+ * 1. Upload video to rupload.facebook.com/messenger_image/ (required for raven)
1283
+ * 2. Broadcast via REST to /direct_v2/threads/broadcast/raven_attachment/
1284
+ *
1285
+ * @param {Object} options
1286
+ * @param {Buffer} options.videoBuffer - The video as a Buffer
1287
+ * @param {string} options.threadId - Thread ID to send to
1288
+ * @param {string} [options.viewMode='once'] - 'once' or 'replayable'
1289
+ * @param {number} [options.duration=0] - Duration in seconds
1290
+ * @param {number} [options.width=720] - Video width
1291
+ * @param {number} [options.height=1280] - Video height
1292
+ * @returns {Promise<Object>} - REST broadcast response
1293
+ */
1294
+ async sendRavenVideo({ videoBuffer, threadId, viewMode = 'once', duration = 0, width = 720, height = 1280 }) {
1295
+ var _a, _b, _c, _d;
1296
+ this.enhancedDebug(`Sending raven video to thread ${threadId} (viewMode: ${viewMode})`);
1297
+ try {
1298
+ if (!videoBuffer || !Buffer.isBuffer(videoBuffer) || videoBuffer.length === 0) {
1299
+ throw new Error('videoBuffer must be a non-empty Buffer');
1300
+ }
1301
+ if (!threadId) {
1302
+ throw new Error('threadId is required');
1303
+ }
1304
+ const ig = this.realtimeClient.ig;
1305
+ if (!ig || !ig.request) {
1306
+ throw new Error('Instagram client not available. Make sure you are logged in.');
1307
+ }
1308
+ const axios = require('axios');
1309
+ this.enhancedDebug(`Step 1: Uploading raven video to messenger_image (${videoBuffer.length} bytes)...`);
1310
+ const uploadId = Date.now().toString();
1311
+ const randomSuffix = Math.floor(Math.random() * (9999999999 - 1000000000) + 1000000000);
1312
+ const name = `${uploadId}_0_${randomSuffix}`;
1313
+ const waterfallId = (0, uuid_1.v4)();
1314
+ const ruploadParams = {
1315
+ upload_media_height: String(height),
1316
+ upload_media_width: String(width),
1317
+ upload_media_duration_ms: String(Math.round(duration * 1000)),
1318
+ upload_id: uploadId,
1319
+ retry_context: '{"num_step_auto_retry":0,"num_reupload":0,"num_step_manual_retry":0}',
1320
+ media_type: '2',
1321
+ xsharing_user_ids: JSON.stringify([]),
1322
+ direct_v2: '1',
1323
+ };
1324
+ const defaultHeaders = ig.request.getDefaultHeaders();
1325
+ const messengerUploadHeaders = {
1326
+ ...defaultHeaders,
1327
+ 'X_FB_VIDEO_WATERFALL_ID': waterfallId,
1328
+ 'X-Entity-Type': 'video/mp4',
1329
+ 'Offset': '0',
1330
+ 'X-Instagram-Rupload-Params': JSON.stringify(ruploadParams),
1331
+ 'X-Entity-Name': name,
1332
+ 'X-Entity-Length': String(videoBuffer.length),
1333
+ 'Content-Type': 'application/octet-stream',
1334
+ 'Content-Length': String(videoBuffer.length),
1335
+ 'ephemeral_media_view_mode': viewMode === 'replayable' ? '1' : '0',
1336
+ 'ig_raven_metadata': '{}',
1337
+ 'Host': 'rupload.facebook.com',
1338
+ };
1339
+ let serverUploadId = uploadId;
1340
+ let attachmentFbid = null;
1341
+ try {
1342
+ const uploadResp = await axios({
1343
+ url: `https://rupload.facebook.com/messenger_image/${name}`,
1344
+ method: 'POST',
1345
+ headers: messengerUploadHeaders,
1346
+ data: videoBuffer,
1347
+ maxBodyLength: Infinity,
1348
+ maxContentLength: Infinity,
1349
+ transformRequest: [(d) => d],
1350
+ });
1351
+ const uploadParsed = uploadResp.data;
1352
+ serverUploadId = (uploadParsed.upload_id || uploadId).toString();
1353
+ attachmentFbid = uploadParsed.media_id
1354
+ || (uploadParsed.media && uploadParsed.media.pk)
1355
+ || null;
1356
+ this.enhancedDebug(`Raven video uploaded! upload_id: ${serverUploadId}, media_id: ${attachmentFbid}`);
1357
+ }
1358
+ catch (uploadErr) {
1359
+ const msg = uploadErr && uploadErr.message ? uploadErr.message : String(uploadErr);
1360
+ this.enhancedDebug(`Raven video upload error: ${msg}`);
1361
+ throw new Error(`Raven video upload failed: ${msg}`);
1362
+ }
1363
+ this.enhancedDebug(`Step 2: Broadcasting via REST to raven_attachment/...`);
1364
+ const clientContext = BigInt(Math.floor(Math.random() * 2 ** 62)).toString();
1365
+ const compositionId = (0, uuid_1.v4)();
1366
+ const cameraSessionId = (0, uuid_1.v4)();
1367
+ const now = Math.floor(Date.now() / 1000);
1368
+ const form = {
1369
+ allow_multi_configures: '1',
1370
+ recipient_users: '[]',
1371
+ view_mode: viewMode,
1372
+ is_shh_mode: '0',
1373
+ camera_entry_point: '3',
1374
+ thread_ids: JSON.stringify([String(threadId)]),
1375
+ reshare_mode: 'allow_reshare',
1376
+ original_media_type: '2',
1377
+ send_attribution: 'direct_thread_camera',
1378
+ client_context: clientContext,
1379
+ camera_session_id: cameraSessionId,
1380
+ include_e2ee_mentioned_user_list: '1',
1381
+ hide_from_profile_grid: 'false',
1382
+ scene_capture_type: '',
1383
+ timezone_offset: String(new Date().getTimezoneOffset() * -60),
1384
+ client_shared_at: String(now),
1385
+ configure_mode: '2',
1386
+ source_type: '4',
1387
+ camera_position: 'unknown',
1388
+ _uid: String(ig.state.cookieUserId || ig.state.igUserId),
1389
+ device_id: ig.state.deviceId,
1390
+ composition_id: compositionId,
1391
+ mutation_token: clientContext,
1392
+ _uuid: ig.state.uuid,
1393
+ creation_tool_info: '[]',
1394
+ creation_surface: 'camera',
1395
+ capture_type: 'normal',
1396
+ audience: 'default',
1397
+ upload_id: serverUploadId,
1398
+ client_timestamp: String(now),
1399
+ sampled: 'true',
1400
+ video_result: '',
1401
+ media_type: '2',
1402
+ media_transformation_info: JSON.stringify({
1403
+ width: String(width), height: String(height),
1404
+ x_transform: '0', y_transform: '0',
1405
+ zoom: '1.0', rotation: '0.0', background_coverage: '0.0',
1406
+ }),
1407
+ extra: JSON.stringify({ source_width: width, source_height: height }),
1408
+ device: JSON.stringify({
1409
+ manufacturer: ((_a = ig.state.devicePayload) === null || _a === void 0 ? void 0 : _a.manufacturer) || 'samsung',
1410
+ model: ((_b = ig.state.devicePayload) === null || _b === void 0 ? void 0 : _b.model) || 'SM-S938B',
1411
+ android_version: ((_c = ig.state.devicePayload) === null || _c === void 0 ? void 0 : _c.android_version) || 35,
1412
+ android_release: ((_d = ig.state.devicePayload) === null || _d === void 0 ? void 0 : _d.android_release) || '15',
1413
+ }),
1414
+ };
1415
+ if (attachmentFbid) {
1416
+ form.attachment_fbid = String(attachmentFbid);
1417
+ }
1418
+ const payloadForm = (ig.request && typeof ig.request.sign === 'function')
1419
+ ? ig.request.sign(form)
1420
+ : form;
1421
+ const result = await ig.request.send({
1422
+ url: '/api/v1/direct_v2/threads/broadcast/raven_attachment/',
1423
+ method: 'POST',
1424
+ form: payloadForm,
1425
+ qs: { use_unified_inbox: true },
1426
+ });
1427
+ const body = result && (result.body || result.data || result);
1428
+ this.enhancedDebug(`Raven video broadcast SUCCESS`);
1429
+ return typeof body === 'string' ? JSON.parse(body) : body;
1430
+ }
1431
+ catch (err) {
1432
+ this.enhancedDebug(`sendRavenVideo failed: ${err && err.message ? err.message : String(err)}`);
1433
+ throw err;
1434
+ }
1435
+ }
1436
+ /**
1437
+ * Send raven video (view once) - convenience wrapper
1438
+ */
1439
+ async sendRavenVideoOnce(options) {
1440
+ return this.sendRavenVideo({ ...options, viewMode: 'once' });
1441
+ }
1442
+ /**
1443
+ * Send raven video (replayable) - convenience wrapper
1444
+ */
1445
+ async sendRavenVideoReplayable(options) {
1446
+ return this.sendRavenVideo({ ...options, viewMode: 'replayable' });
1447
+ }
1448
+ /**
1449
+ * Mark visual message as seen via REST API (with MQTT fallback)
1450
+ */
1451
+ async markVisualMessageSeen({ threadId, itemId, clientContext }) {
1452
+ this.enhancedDebug(`Marking visual message ${itemId} as seen`);
1453
+ const ig = this.realtimeClient && this.realtimeClient.ig;
1454
+ if (ig && ig.request) {
1455
+ try {
1456
+ const ctx = clientContext || (0, uuid_1.v4)();
1457
+ const form = {
1458
+ _uuid: ig.state.uuid,
1459
+ device_id: ig.state.deviceId,
1460
+ use_unified_inbox: true,
1461
+ action: 'mark_visual_item_seen',
1462
+ thread_id: threadId,
1463
+ item_id: itemId,
1464
+ client_context: ctx,
1465
+ mutation_token: ctx,
1466
+ };
1467
+ const response = await ig.request.send({
1468
+ url: `/api/v1/direct_v2/threads/${threadId}/items/${itemId}/seen/`,
1469
+ method: 'POST',
1470
+ form: form,
1471
+ });
1472
+ const body = response.body || response.data || response;
1473
+ const parsed = typeof body === 'string' ? JSON.parse(body) : body;
1474
+ if (parsed && parsed.status === 'ok') {
1475
+ this.enhancedDebug(`✅ Visual message marked as seen via REST API! Status: ok`);
1476
+ return parsed;
1477
+ }
1478
+ this.enhancedDebug(`REST mark_visual_item_seen response: ${JSON.stringify(parsed).slice(0, 300)}`);
1479
+ return parsed;
1480
+ }
1481
+ catch (restErr) {
1482
+ this.enhancedDebug(`REST mark_visual_item_seen failed: ${restErr && restErr.message ? restErr.message : String(restErr)}, falling back to MQTT`);
1483
+ }
1484
+ }
1485
+ const result = await this.sendCommand({
1486
+ action: 'mark_visual_item_seen',
1487
+ threadId,
1488
+ clientContext: clientContext || (0, uuid_1.v4)(),
1489
+ data: {
1490
+ item_id: itemId,
1491
+ },
1492
+ });
1493
+ this.enhancedDebug(`⚠️ Visual message mark_seen sent via MQTT (fallback - may not be processed by Instagram)`);
1494
+ return result;
1495
+ }
1496
+ /**
1497
+ * Screenshot notification via MQTT
1498
+ */
1499
+ async sendScreenshotNotification({ threadId, itemId, clientContext }) {
1500
+ this.enhancedDebug(`Sending screenshot notification for ${itemId}`);
1501
+ const result = await this.sendCommand({
1502
+ action: 'screenshot_notification',
1503
+ threadId,
1504
+ clientContext: clientContext || (0, uuid_1.v4)(),
1505
+ data: {
1506
+ item_id: itemId,
1507
+ },
1508
+ });
1509
+ this.enhancedDebug(`✅ Screenshot notification sent via MQTT!`);
1510
+ return result;
1511
+ }
1512
+ /**
1513
+ * Replay notification via MQTT
1514
+ */
1515
+ async sendReplayNotification({ threadId, itemId, clientContext }) {
1516
+ this.enhancedDebug(`Sending replay notification for ${itemId}`);
1517
+ const result = await this.sendCommand({
1518
+ action: 'replay_notification',
1519
+ threadId,
1520
+ clientContext: clientContext || (0, uuid_1.v4)(),
1521
+ data: {
1522
+ item_id: itemId,
1523
+ },
1524
+ });
1525
+ this.enhancedDebug(`✅ Replay notification sent via MQTT!`);
1526
+ return result;
1527
+ }
1528
+ }
1529
+ exports.EnhancedDirectCommands = EnhancedDirectCommands;