nodejs-insta-private-api-mqtt 1.0.0

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 (210) hide show
  1. package/README.md +1650 -0
  2. package/dist/constants/constants.js +280 -0
  3. package/dist/constants/index.js +41 -0
  4. package/dist/core/client.js +243 -0
  5. package/dist/core/repository.js +7 -0
  6. package/dist/core/request.js +212 -0
  7. package/dist/core/state.js +1456 -0
  8. package/dist/core/utils.js +786 -0
  9. package/dist/downloadMedia.js +381 -0
  10. package/dist/errors/index.d.ts +16 -0
  11. package/dist/errors/index.js +30 -0
  12. package/dist/errors/index.js.map +1 -0
  13. package/dist/fbns/fbns.client.d.ts +32 -0
  14. package/dist/fbns/fbns.client.events.d.ts +41 -0
  15. package/dist/fbns/fbns.client.events.js +3 -0
  16. package/dist/fbns/fbns.client.events.js.map +1 -0
  17. package/dist/fbns/fbns.client.js +179 -0
  18. package/dist/fbns/fbns.client.js.map +1 -0
  19. package/dist/fbns/fbns.device-auth.d.ts +17 -0
  20. package/dist/fbns/fbns.device-auth.js +54 -0
  21. package/dist/fbns/fbns.device-auth.js.map +1 -0
  22. package/dist/fbns/fbns.types.d.ts +83 -0
  23. package/dist/fbns/fbns.types.js +3 -0
  24. package/dist/fbns/fbns.types.js.map +1 -0
  25. package/dist/fbns/fbns.utilities.d.ts +2 -0
  26. package/dist/fbns/fbns.utilities.js +79 -0
  27. package/dist/fbns/fbns.utilities.js.map +1 -0
  28. package/dist/fbns/index.d.ts +4 -0
  29. package/dist/fbns/index.js +21 -0
  30. package/dist/fbns/index.js.map +1 -0
  31. package/dist/index.js +39 -0
  32. package/dist/mqttot/index.d.ts +4 -0
  33. package/dist/mqttot/index.js +21 -0
  34. package/dist/mqttot/index.js.map +1 -0
  35. package/dist/mqttot/mqttot.client.d.ts +39 -0
  36. package/dist/mqttot/mqttot.client.js +120 -0
  37. package/dist/mqttot/mqttot.client.js.map +1 -0
  38. package/dist/mqttot/mqttot.connect.request.packet.d.ts +7 -0
  39. package/dist/mqttot/mqttot.connect.request.packet.js +9 -0
  40. package/dist/mqttot/mqttot.connect.request.packet.js.map +1 -0
  41. package/dist/mqttot/mqttot.connect.response.packet.d.ts +7 -0
  42. package/dist/mqttot/mqttot.connect.response.packet.js +24 -0
  43. package/dist/mqttot/mqttot.connect.response.packet.js.map +1 -0
  44. package/dist/mqttot/mqttot.connection.d.ts +57 -0
  45. package/dist/mqttot/mqttot.connection.js +56 -0
  46. package/dist/mqttot/mqttot.connection.js.map +1 -0
  47. package/dist/package.json +59 -0
  48. package/dist/realtime/commands/commands.d.ts +15 -0
  49. package/dist/realtime/commands/commands.js +21 -0
  50. package/dist/realtime/commands/commands.js.map +1 -0
  51. package/dist/realtime/commands/direct.commands.d.ts +75 -0
  52. package/dist/realtime/commands/direct.commands.js +186 -0
  53. package/dist/realtime/commands/direct.commands.js.map +1 -0
  54. package/dist/realtime/commands/enhanced.direct.commands.js +987 -0
  55. package/dist/realtime/commands/index.d.ts +2 -0
  56. package/dist/realtime/commands/index.js +19 -0
  57. package/dist/realtime/commands/index.js.map +1 -0
  58. package/dist/realtime/delta-sync.manager.js +293 -0
  59. package/dist/realtime/features/dm-sender.js +88 -0
  60. package/dist/realtime/features/error-handler.js +73 -0
  61. package/dist/realtime/features/gap-handler.js +61 -0
  62. package/dist/realtime/features/presence.manager.js +66 -0
  63. package/dist/realtime/index.js +30 -0
  64. package/dist/realtime/messages/app-presence.event.d.ts +9 -0
  65. package/dist/realtime/messages/app-presence.event.js +3 -0
  66. package/dist/realtime/messages/app-presence.event.js.map +1 -0
  67. package/dist/realtime/messages/index.d.ts +3 -0
  68. package/dist/realtime/messages/index.js +20 -0
  69. package/dist/realtime/messages/index.js.map +1 -0
  70. package/dist/realtime/messages/message-sync.message.d.ts +222 -0
  71. package/dist/realtime/messages/message-sync.message.js +43 -0
  72. package/dist/realtime/messages/message-sync.message.js.map +1 -0
  73. package/dist/realtime/messages/realtime-sub.direct.data.d.ts +11 -0
  74. package/dist/realtime/messages/realtime-sub.direct.data.js +3 -0
  75. package/dist/realtime/messages/realtime-sub.direct.data.js.map +1 -0
  76. package/dist/realtime/messages/thread-update.message.d.ts +68 -0
  77. package/dist/realtime/messages/thread-update.message.js +3 -0
  78. package/dist/realtime/messages/thread-update.message.js.map +1 -0
  79. package/dist/realtime/mixins/index.d.ts +3 -0
  80. package/dist/realtime/mixins/index.js +20 -0
  81. package/dist/realtime/mixins/index.js.map +1 -0
  82. package/dist/realtime/mixins/message-sync.mixin.d.ts +8 -0
  83. package/dist/realtime/mixins/message-sync.mixin.js +381 -0
  84. package/dist/realtime/mixins/message-sync.mixin.js.map +1 -0
  85. package/dist/realtime/mixins/mixin.d.ts +19 -0
  86. package/dist/realtime/mixins/mixin.js +41 -0
  87. package/dist/realtime/mixins/mixin.js.map +1 -0
  88. package/dist/realtime/mixins/presence-typing.mixin.js +33 -0
  89. package/dist/realtime/mixins/realtime-sub.mixin.d.ts +8 -0
  90. package/dist/realtime/mixins/realtime-sub.mixin.js +55 -0
  91. package/dist/realtime/mixins/realtime-sub.mixin.js.map +1 -0
  92. package/dist/realtime/parsers/graphql-parser.js +43 -0
  93. package/dist/realtime/parsers/graphql.parser.d.ts +15 -0
  94. package/dist/realtime/parsers/graphql.parser.js +22 -0
  95. package/dist/realtime/parsers/graphql.parser.js.map +1 -0
  96. package/dist/realtime/parsers/index.d.ts +6 -0
  97. package/dist/realtime/parsers/index.js +23 -0
  98. package/dist/realtime/parsers/index.js.map +1 -0
  99. package/dist/realtime/parsers/iris-parser.js +43 -0
  100. package/dist/realtime/parsers/iris.parser.d.ts +17 -0
  101. package/dist/realtime/parsers/iris.parser.js +10 -0
  102. package/dist/realtime/parsers/iris.parser.js.map +1 -0
  103. package/dist/realtime/parsers/json-parser.js +43 -0
  104. package/dist/realtime/parsers/json.parser.d.ts +6 -0
  105. package/dist/realtime/parsers/json.parser.js +10 -0
  106. package/dist/realtime/parsers/json.parser.js.map +1 -0
  107. package/dist/realtime/parsers/parser.d.ts +9 -0
  108. package/dist/realtime/parsers/parser.js +3 -0
  109. package/dist/realtime/parsers/parser.js.map +1 -0
  110. package/dist/realtime/parsers/region-hint-parser.js +43 -0
  111. package/dist/realtime/parsers/region-hint.parser.d.ts +12 -0
  112. package/dist/realtime/parsers/region-hint.parser.js +15 -0
  113. package/dist/realtime/parsers/region-hint.parser.js.map +1 -0
  114. package/dist/realtime/parsers/skywalker-parser.js +43 -0
  115. package/dist/realtime/parsers/skywalker.parser.d.ts +12 -0
  116. package/dist/realtime/parsers/skywalker.parser.js +15 -0
  117. package/dist/realtime/parsers/skywalker.parser.js.map +1 -0
  118. package/dist/realtime/parsers-advanced.js +158 -0
  119. package/dist/realtime/proto/common.proto +38 -0
  120. package/dist/realtime/proto/direct.proto +65 -0
  121. package/dist/realtime/proto/ig-messages.proto +83 -0
  122. package/dist/realtime/proto/iris.proto +188 -0
  123. package/dist/realtime/proto-parser.js +195 -0
  124. package/dist/realtime/protocols/iris.handshake.js +74 -0
  125. package/dist/realtime/protocols/proto-definitions.js +80 -0
  126. package/dist/realtime/protocols/skywalker.protocol.js +91 -0
  127. package/dist/realtime/realtime.client.events.js +3 -0
  128. package/dist/realtime/realtime.client.js +449 -0
  129. package/dist/realtime/realtime.service.js +462 -0
  130. package/dist/realtime/reconnect.manager.js +94 -0
  131. package/dist/realtime/session.manager.js +121 -0
  132. package/dist/realtime/subscriptions/graphql.subscription.d.ts +47 -0
  133. package/dist/realtime/subscriptions/graphql.subscription.js +99 -0
  134. package/dist/realtime/subscriptions/graphql.subscription.js.map +1 -0
  135. package/dist/realtime/subscriptions/index.d.ts +2 -0
  136. package/dist/realtime/subscriptions/index.js +19 -0
  137. package/dist/realtime/subscriptions/index.js.map +1 -0
  138. package/dist/realtime/subscriptions/skywalker.subscription.d.ts +4 -0
  139. package/dist/realtime/subscriptions/skywalker.subscription.js +13 -0
  140. package/dist/realtime/subscriptions/skywalker.subscription.js.map +1 -0
  141. package/dist/realtime/topic-map.js +71 -0
  142. package/dist/realtime/topic.js +80 -0
  143. package/dist/repositories/account.repository.js +261 -0
  144. package/dist/repositories/direct-thread.repository.js +247 -0
  145. package/dist/repositories/direct.repository.js +153 -0
  146. package/dist/repositories/feed.repository.js +233 -0
  147. package/dist/repositories/friendship.repository.js +190 -0
  148. package/dist/repositories/hashtag.repository.js +101 -0
  149. package/dist/repositories/highlights.repository.js +127 -0
  150. package/dist/repositories/location.repository.js +84 -0
  151. package/dist/repositories/media.repository.js +165 -0
  152. package/dist/repositories/story.repository.js +156 -0
  153. package/dist/repositories/upload.repository.js +167 -0
  154. package/dist/repositories/user.repository.js +94 -0
  155. package/dist/sendmedia/index.js +11 -0
  156. package/dist/sendmedia/sendFile.js +154 -0
  157. package/dist/sendmedia/sendPhoto.js +145 -0
  158. package/dist/sendmedia/uploadPhoto.js +175 -0
  159. package/dist/sendmedia/uploadfFile.js +264 -0
  160. package/dist/services/live.service.js +147 -0
  161. package/dist/services/search.service.js +116 -0
  162. package/dist/shared/index.js +35 -0
  163. package/dist/shared/shared.js +86 -0
  164. package/dist/thrift/index.d.ts +3 -0
  165. package/dist/thrift/index.js +20 -0
  166. package/dist/thrift/index.js.map +1 -0
  167. package/dist/thrift/thrift.d.ts +59 -0
  168. package/dist/thrift/thrift.js +101 -0
  169. package/dist/thrift/thrift.js.map +1 -0
  170. package/dist/thrift/thrift.reading.d.ts +41 -0
  171. package/dist/thrift/thrift.reading.js +327 -0
  172. package/dist/thrift/thrift.reading.js.map +1 -0
  173. package/dist/thrift/thrift.writing.d.ts +44 -0
  174. package/dist/thrift/thrift.writing.js +342 -0
  175. package/dist/thrift/thrift.writing.js.map +1 -0
  176. package/dist/types/index.js +285 -0
  177. package/dist/useMultiFileAuthState.js +437 -0
  178. package/dist/utils/helper-1.js +1 -0
  179. package/dist/utils/helper-10.js +1 -0
  180. package/dist/utils/helper-11.js +1 -0
  181. package/dist/utils/helper-12.js +1 -0
  182. package/dist/utils/helper-13.js +1 -0
  183. package/dist/utils/helper-14.js +1 -0
  184. package/dist/utils/helper-15.js +1 -0
  185. package/dist/utils/helper-16.js +1 -0
  186. package/dist/utils/helper-17.js +1 -0
  187. package/dist/utils/helper-18.js +1 -0
  188. package/dist/utils/helper-19.js +1 -0
  189. package/dist/utils/helper-2.js +1 -0
  190. package/dist/utils/helper-20.js +1 -0
  191. package/dist/utils/helper-21.js +1 -0
  192. package/dist/utils/helper-22.js +1 -0
  193. package/dist/utils/helper-23.js +1 -0
  194. package/dist/utils/helper-24.js +1 -0
  195. package/dist/utils/helper-25.js +1 -0
  196. package/dist/utils/helper-26.js +1 -0
  197. package/dist/utils/helper-27.js +1 -0
  198. package/dist/utils/helper-28.js +1 -0
  199. package/dist/utils/helper-29.js +1 -0
  200. package/dist/utils/helper-3.js +1 -0
  201. package/dist/utils/helper-30.js +1 -0
  202. package/dist/utils/helper-4.js +1 -0
  203. package/dist/utils/helper-5.js +1 -0
  204. package/dist/utils/helper-6.js +1 -0
  205. package/dist/utils/helper-7.js +1 -0
  206. package/dist/utils/helper-8.js +1 -0
  207. package/dist/utils/helper-9.js +1 -0
  208. package/dist/utils/index.js +280 -0
  209. package/examples/listen-to-messages.js +86 -0
  210. package/package.json +79 -0
@@ -0,0 +1,987 @@
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
+
8
+ /**
9
+ * Enhanced Direct Commands - sends MQTT directly with proper payload formatting
10
+ */
11
+ class EnhancedDirectCommands {
12
+ constructor(client) {
13
+ this.realtimeClient = client;
14
+ this.enhancedDebug = (0, shared_1.debugChannel)('realtime', 'enhanced-commands');
15
+ }
16
+
17
+ /**
18
+ * Send text via MQTT with proper payload format
19
+ */
20
+ async sendTextViaRealtime(threadId, text) {
21
+ this.enhancedDebug(`Sending text to ${threadId}: "${text}"`);
22
+
23
+ try {
24
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
25
+ if (!mqtt || typeof mqtt.publish !== 'function') {
26
+ throw new Error('MQTT client not available');
27
+ }
28
+
29
+ // Build proper command payload
30
+ const clientContext = (0, uuid_1.v4)();
31
+ const command = {
32
+ action: 'send_item',
33
+ thread_id: threadId,
34
+ item_type: 'text',
35
+ text: text,
36
+ timestamp: Date.now(),
37
+ client_context: clientContext,
38
+ };
39
+
40
+ // Compress JSON payload
41
+ const json = JSON.stringify(command);
42
+ const { compressDeflate } = shared_1;
43
+ const payload = await compressDeflate(json);
44
+
45
+ // Send to MQTT
46
+ this.enhancedDebug(`Publishing to MQTT topic ${constants_1.Topics.SEND_MESSAGE.id}`);
47
+ const result = await mqtt.publish({
48
+ topic: constants_1.Topics.SEND_MESSAGE.id,
49
+ qosLevel: 1,
50
+ payload: payload,
51
+ });
52
+
53
+ this.enhancedDebug(`✅ Message sent via MQTT!`);
54
+ return result;
55
+ } catch (err) {
56
+ this.enhancedDebug(`Failed: ${err.message}`);
57
+ throw err;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Delete message via MQTT
63
+ */
64
+ async deleteMessage(threadId, itemId) {
65
+ this.enhancedDebug(`Deleting message ${itemId} from thread ${threadId}`);
66
+
67
+ try {
68
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
69
+ if (!mqtt || typeof mqtt.publish !== 'function') {
70
+ throw new Error('MQTT client not available');
71
+ }
72
+
73
+ const clientContext = (0, uuid_1.v4)();
74
+ const command = {
75
+ action: 'delete_item',
76
+ thread_id: threadId,
77
+ item_id: itemId,
78
+ timestamp: Date.now(),
79
+ client_context: clientContext,
80
+ };
81
+
82
+ const json = JSON.stringify(command);
83
+ const { compressDeflate } = shared_1;
84
+ const payload = await compressDeflate(json);
85
+
86
+ this.enhancedDebug(`Publishing delete command to MQTT topic ${constants_1.Topics.SEND_MESSAGE.id}`);
87
+ const result = await mqtt.publish({
88
+ topic: constants_1.Topics.SEND_MESSAGE.id,
89
+ qosLevel: 1,
90
+ payload: payload,
91
+ });
92
+
93
+ this.enhancedDebug(`✅ Message deleted via MQTT!`);
94
+ return result;
95
+ } catch (err) {
96
+ this.enhancedDebug(`Delete failed: ${err.message}`);
97
+ throw err;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Edit message via MQTT
103
+ */
104
+ async editMessage(threadId, itemId, newText) {
105
+ this.enhancedDebug(`Editing message ${itemId}: "${newText}"`);
106
+
107
+ try {
108
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
109
+ if (!mqtt || typeof mqtt.publish !== 'function') {
110
+ throw new Error('MQTT client not available');
111
+ }
112
+
113
+ const clientContext = (0, uuid_1.v4)();
114
+ const command = {
115
+ action: 'edit_item',
116
+ thread_id: threadId,
117
+ item_id: itemId,
118
+ text: newText,
119
+ timestamp: Date.now(),
120
+ client_context: clientContext,
121
+ };
122
+
123
+ const json = JSON.stringify(command);
124
+ const { compressDeflate } = shared_1;
125
+ const payload = await compressDeflate(json);
126
+
127
+ this.enhancedDebug(`Publishing edit command to MQTT topic ${constants_1.Topics.SEND_MESSAGE.id}`);
128
+ const result = await mqtt.publish({
129
+ topic: constants_1.Topics.SEND_MESSAGE.id,
130
+ qosLevel: 1,
131
+ payload: payload,
132
+ });
133
+
134
+ this.enhancedDebug(`✅ Message edited via MQTT!`);
135
+ return result;
136
+ } catch (err) {
137
+ this.enhancedDebug(`Edit failed: ${err.message}`);
138
+ throw err;
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Reply to message via MQTT (Quote Reply)
144
+ */
145
+ async replyToMessage(threadId, messageId, replyText) {
146
+ this.enhancedDebug(`Replying to ${messageId} in thread ${threadId}: "${replyText}"`);
147
+
148
+ try {
149
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
150
+ if (!mqtt || typeof mqtt.publish !== 'function') {
151
+ throw new Error('MQTT client not available');
152
+ }
153
+
154
+ const clientContext = (0, uuid_1.v4)();
155
+ const command = {
156
+ action: 'send_item',
157
+ thread_id: threadId,
158
+ item_type: 'text',
159
+ text: replyText,
160
+ replying_to_item_id: messageId,
161
+ timestamp: Date.now(),
162
+ client_context: clientContext,
163
+ };
164
+
165
+ const json = JSON.stringify(command);
166
+ const { compressDeflate } = shared_1;
167
+ const payload = await compressDeflate(json);
168
+
169
+ this.enhancedDebug(`Publishing reply command to MQTT topic ${constants_1.Topics.SEND_MESSAGE.id}`);
170
+ const result = await mqtt.publish({
171
+ topic: constants_1.Topics.SEND_MESSAGE.id,
172
+ qosLevel: 1,
173
+ payload: payload,
174
+ });
175
+
176
+ this.enhancedDebug(`✅ Reply sent via MQTT!`);
177
+ return result;
178
+ } catch (err) {
179
+ this.enhancedDebug(`Reply failed: ${err.message}`);
180
+ throw err;
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Subscribe to follow notifications via MQTT
186
+ */
187
+ async subscribeToFollowNotifications() {
188
+ this.enhancedDebug(`Subscribing to follow notifications via MQTT`);
189
+
190
+ try {
191
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
192
+ if (!mqtt || typeof mqtt.publish !== 'function') {
193
+ throw new Error('MQTT client not available');
194
+ }
195
+
196
+ const clientContext = (0, uuid_1.v4)();
197
+ const command = {
198
+ action: 'subscribe',
199
+ subscription_type: 'follow_notifications',
200
+ timestamp: Date.now(),
201
+ client_context: clientContext,
202
+ };
203
+
204
+ const json = JSON.stringify(command);
205
+ const { compressDeflate } = shared_1;
206
+ const payload = await compressDeflate(json);
207
+
208
+ this.enhancedDebug(`Publishing follow subscription to MQTT`);
209
+ const result = await mqtt.publish({
210
+ topic: constants_1.Topics.SEND_MESSAGE.id,
211
+ qosLevel: 1,
212
+ payload: payload,
213
+ });
214
+
215
+ this.enhancedDebug(`✅ Follow notifications subscribed via MQTT!`);
216
+ return result;
217
+ } catch (err) {
218
+ this.enhancedDebug(`Follow subscription failed: ${err.message}`);
219
+ throw err;
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Subscribe to mention notifications via MQTT
225
+ */
226
+ async subscribeToMentionNotifications() {
227
+ this.enhancedDebug(`Subscribing to mention notifications via MQTT`);
228
+
229
+ try {
230
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
231
+ if (!mqtt || typeof mqtt.publish !== 'function') {
232
+ throw new Error('MQTT client not available');
233
+ }
234
+
235
+ const clientContext = (0, uuid_1.v4)();
236
+ const command = {
237
+ action: 'subscribe',
238
+ subscription_type: 'mention_notifications',
239
+ timestamp: Date.now(),
240
+ client_context: clientContext,
241
+ };
242
+
243
+ const json = JSON.stringify(command);
244
+ const { compressDeflate } = shared_1;
245
+ const payload = await compressDeflate(json);
246
+
247
+ this.enhancedDebug(`Publishing mention subscription to MQTT`);
248
+ const result = await mqtt.publish({
249
+ topic: constants_1.Topics.SEND_MESSAGE.id,
250
+ qosLevel: 1,
251
+ payload: payload,
252
+ });
253
+
254
+ this.enhancedDebug(`✅ Mention notifications subscribed via MQTT!`);
255
+ return result;
256
+ } catch (err) {
257
+ this.enhancedDebug(`Mention subscription failed: ${err.message}`);
258
+ throw err;
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Subscribe to call notifications via MQTT
264
+ */
265
+ async subscribeToCallNotifications() {
266
+ this.enhancedDebug(`Subscribing to call notifications via MQTT`);
267
+
268
+ try {
269
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
270
+ if (!mqtt || typeof mqtt.publish !== 'function') {
271
+ throw new Error('MQTT client not available');
272
+ }
273
+
274
+ const clientContext = (0, uuid_1.v4)();
275
+ const command = {
276
+ action: 'subscribe',
277
+ subscription_type: 'call_notifications',
278
+ timestamp: Date.now(),
279
+ client_context: clientContext,
280
+ };
281
+
282
+ const json = JSON.stringify(command);
283
+ const { compressDeflate } = shared_1;
284
+ const payload = await compressDeflate(json);
285
+
286
+ this.enhancedDebug(`Publishing call subscription to MQTT`);
287
+ const result = await mqtt.publish({
288
+ topic: constants_1.Topics.SEND_MESSAGE.id,
289
+ qosLevel: 1,
290
+ payload: payload,
291
+ });
292
+
293
+ this.enhancedDebug(`✅ Call notifications subscribed via MQTT!`);
294
+ return result;
295
+ } catch (err) {
296
+ this.enhancedDebug(`Call subscription failed: ${err.message}`);
297
+ throw err;
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Add member to thread via MQTT
303
+ */
304
+ async addMemberToThread(threadId, userId) {
305
+ this.enhancedDebug(`Adding user ${userId} to thread ${threadId} via MQTT`);
306
+
307
+ try {
308
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
309
+ if (!mqtt || typeof mqtt.publish !== 'function') {
310
+ throw new Error('MQTT client not available');
311
+ }
312
+
313
+ const clientContext = (0, uuid_1.v4)();
314
+ const command = {
315
+ action: 'add_member',
316
+ thread_id: threadId,
317
+ user_id: userId,
318
+ timestamp: Date.now(),
319
+ client_context: clientContext,
320
+ };
321
+
322
+ const json = JSON.stringify(command);
323
+ const { compressDeflate } = shared_1;
324
+ const payload = await compressDeflate(json);
325
+
326
+ this.enhancedDebug(`Publishing add member command to MQTT`);
327
+ const result = await mqtt.publish({
328
+ topic: constants_1.Topics.SEND_MESSAGE.id,
329
+ qosLevel: 1,
330
+ payload: payload,
331
+ });
332
+
333
+ this.enhancedDebug(`✅ Member added to thread via MQTT!`);
334
+ return result;
335
+ } catch (err) {
336
+ this.enhancedDebug(`Add member failed: ${err.message}`);
337
+ throw err;
338
+ }
339
+ }
340
+
341
+ /**
342
+ * Remove member from thread via MQTT
343
+ */
344
+ async removeMemberFromThread(threadId, userId) {
345
+ this.enhancedDebug(`Removing user ${userId} from thread ${threadId} via MQTT`);
346
+
347
+ try {
348
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
349
+ if (!mqtt || typeof mqtt.publish !== 'function') {
350
+ throw new Error('MQTT client not available');
351
+ }
352
+
353
+ const clientContext = (0, uuid_1.v4)();
354
+ const command = {
355
+ action: 'remove_member',
356
+ thread_id: threadId,
357
+ user_id: userId,
358
+ timestamp: Date.now(),
359
+ client_context: clientContext,
360
+ };
361
+
362
+ const json = JSON.stringify(command);
363
+ const { compressDeflate } = shared_1;
364
+ const payload = await compressDeflate(json);
365
+
366
+ this.enhancedDebug(`Publishing remove member command to MQTT`);
367
+ const result = await mqtt.publish({
368
+ topic: constants_1.Topics.SEND_MESSAGE.id,
369
+ qosLevel: 1,
370
+ payload: payload,
371
+ });
372
+
373
+ this.enhancedDebug(`✅ Member removed from thread via MQTT!`);
374
+ return result;
375
+ } catch (err) {
376
+ this.enhancedDebug(`Remove member failed: ${err.message}`);
377
+ throw err;
378
+ }
379
+ }
380
+
381
+ /**
382
+ * Send reaction (emoji) via MQTT
383
+ */
384
+ async sendReaction({ itemId, reactionType = 'like', clientContext, threadId, reactionStatus = 'created', emoji }) {
385
+ this.enhancedDebug(`Sending ${reactionType} reaction to message ${itemId} via MQTT`);
386
+
387
+ try {
388
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
389
+ if (!mqtt || typeof mqtt.publish !== 'function') {
390
+ throw new Error('MQTT client not available');
391
+ }
392
+
393
+ const ctx = clientContext || (0, uuid_1.v4)();
394
+ const command = {
395
+ action: 'send_reaction',
396
+ thread_id: threadId,
397
+ item_id: itemId,
398
+ reaction_type: reactionType,
399
+ reaction_status: reactionStatus,
400
+ emoji: emoji || '',
401
+ timestamp: Date.now(),
402
+ client_context: ctx,
403
+ };
404
+
405
+ const json = JSON.stringify(command);
406
+ const { compressDeflate } = shared_1;
407
+ const payload = await compressDeflate(json);
408
+
409
+ this.enhancedDebug(`Publishing reaction to MQTT`);
410
+ const result = await mqtt.publish({
411
+ topic: constants_1.Topics.SEND_MESSAGE.id,
412
+ qosLevel: 1,
413
+ payload: payload,
414
+ });
415
+
416
+ this.enhancedDebug(`✅ Reaction sent via MQTT!`);
417
+ return result;
418
+ } catch (err) {
419
+ this.enhancedDebug(`Reaction failed: ${err.message}`);
420
+ throw err;
421
+ }
422
+ }
423
+
424
+ /**
425
+ * Mark message as seen via MQTT
426
+ */
427
+ async markAsSeen({ threadId, itemId }) {
428
+ this.enhancedDebug(`Marking message ${itemId} as seen in thread ${threadId} via MQTT`);
429
+
430
+ try {
431
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
432
+ if (!mqtt || typeof mqtt.publish !== 'function') {
433
+ throw new Error('MQTT client not available');
434
+ }
435
+
436
+ const clientContext = (0, uuid_1.v4)();
437
+ const command = {
438
+ action: 'mark_as_seen',
439
+ thread_id: threadId,
440
+ item_id: itemId,
441
+ timestamp: Date.now(),
442
+ client_context: clientContext,
443
+ };
444
+
445
+ const json = JSON.stringify(command);
446
+ const { compressDeflate } = shared_1;
447
+ const payload = await compressDeflate(json);
448
+
449
+ this.enhancedDebug(`Publishing mark as seen to MQTT`);
450
+ const result = await mqtt.publish({
451
+ topic: constants_1.Topics.SEND_MESSAGE.id,
452
+ qosLevel: 1,
453
+ payload: payload,
454
+ });
455
+
456
+ this.enhancedDebug(`✅ Message marked as seen via MQTT!`);
457
+ return result;
458
+ } catch (err) {
459
+ this.enhancedDebug(`Mark as seen failed: ${err.message}`);
460
+ throw err;
461
+ }
462
+ }
463
+
464
+ /**
465
+ * Indicate activity (typing) via MQTT
466
+ */
467
+ async indicateActivity({ threadId, isActive = true, clientContext }) {
468
+ this.enhancedDebug(`Indicating ${isActive ? 'typing' : 'stopped'} in thread ${threadId} via MQTT`);
469
+
470
+ try {
471
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
472
+ if (!mqtt || typeof mqtt.publish !== 'function') {
473
+ throw new Error('MQTT client not available');
474
+ }
475
+
476
+ const ctx = clientContext || (0, uuid_1.v4)();
477
+ const command = {
478
+ action: 'indicate_activity',
479
+ thread_id: threadId,
480
+ is_active: isActive,
481
+ timestamp: Date.now(),
482
+ client_context: ctx,
483
+ };
484
+
485
+ const json = JSON.stringify(command);
486
+ const { compressDeflate } = shared_1;
487
+ const payload = await compressDeflate(json);
488
+
489
+ this.enhancedDebug(`Publishing activity indicator to MQTT`);
490
+ const result = await mqtt.publish({
491
+ topic: constants_1.Topics.SEND_MESSAGE.id,
492
+ qosLevel: 1,
493
+ payload: payload,
494
+ });
495
+
496
+ this.enhancedDebug(`✅ Activity indicator sent via MQTT!`);
497
+ return result;
498
+ } catch (err) {
499
+ this.enhancedDebug(`Activity indicator failed: ${err.message}`);
500
+ throw err;
501
+ }
502
+ }
503
+
504
+ /**
505
+ * Send media (image/video) via MQTT
506
+ */
507
+ async sendMedia({ text, mediaId, threadId, clientContext }) {
508
+ this.enhancedDebug(`Sending media ${mediaId} to ${threadId} via MQTT`);
509
+
510
+ try {
511
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
512
+ if (!mqtt || typeof mqtt.publish !== 'function') {
513
+ throw new Error('MQTT client not available');
514
+ }
515
+
516
+ const ctx = clientContext || (0, uuid_1.v4)();
517
+ const command = {
518
+ action: 'send_item',
519
+ thread_id: threadId,
520
+ item_type: 'media',
521
+ media_id: mediaId,
522
+ text: text || '',
523
+ timestamp: Date.now(),
524
+ client_context: ctx,
525
+ };
526
+
527
+ const json = JSON.stringify(command);
528
+ const { compressDeflate } = shared_1;
529
+ const payload = await compressDeflate(json);
530
+
531
+ this.enhancedDebug(`Publishing media to MQTT`);
532
+ const result = await mqtt.publish({
533
+ topic: constants_1.Topics.SEND_MESSAGE.id,
534
+ qosLevel: 1,
535
+ payload: payload,
536
+ });
537
+
538
+ this.enhancedDebug(`✅ Media sent via MQTT!`);
539
+ return result;
540
+ } catch (err) {
541
+ this.enhancedDebug(`Media send failed: ${err.message}`);
542
+ throw err;
543
+ }
544
+ }
545
+
546
+ /**
547
+ * Send location via MQTT
548
+ */
549
+ async sendLocation({ text, locationId, threadId, clientContext }) {
550
+ this.enhancedDebug(`Sending location ${locationId} to ${threadId} via MQTT`);
551
+
552
+ try {
553
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
554
+ if (!mqtt || typeof mqtt.publish !== 'function') {
555
+ throw new Error('MQTT client not available');
556
+ }
557
+
558
+ const ctx = clientContext || (0, uuid_1.v4)();
559
+ const command = {
560
+ action: 'send_item',
561
+ thread_id: threadId,
562
+ item_type: 'location',
563
+ location_id: locationId,
564
+ text: text || '',
565
+ timestamp: Date.now(),
566
+ client_context: ctx,
567
+ };
568
+
569
+ const json = JSON.stringify(command);
570
+ const { compressDeflate } = shared_1;
571
+ const payload = await compressDeflate(json);
572
+
573
+ this.enhancedDebug(`Publishing location to MQTT`);
574
+ const result = await mqtt.publish({
575
+ topic: constants_1.Topics.SEND_MESSAGE.id,
576
+ qosLevel: 1,
577
+ payload: payload,
578
+ });
579
+
580
+ this.enhancedDebug(`✅ Location sent via MQTT!`);
581
+ return result;
582
+ } catch (err) {
583
+ this.enhancedDebug(`Location send failed: ${err.message}`);
584
+ throw err;
585
+ }
586
+ }
587
+
588
+ /**
589
+ * Send profile via MQTT
590
+ */
591
+ async sendProfile({ text, userId, threadId, clientContext }) {
592
+ this.enhancedDebug(`Sending profile ${userId} to ${threadId} via MQTT`);
593
+
594
+ try {
595
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
596
+ if (!mqtt || typeof mqtt.publish !== 'function') {
597
+ throw new Error('MQTT client not available');
598
+ }
599
+
600
+ const ctx = clientContext || (0, uuid_1.v4)();
601
+ const command = {
602
+ action: 'send_item',
603
+ thread_id: threadId,
604
+ item_type: 'profile',
605
+ user_id: userId,
606
+ text: text || '',
607
+ timestamp: Date.now(),
608
+ client_context: ctx,
609
+ };
610
+
611
+ const json = JSON.stringify(command);
612
+ const { compressDeflate } = shared_1;
613
+ const payload = await compressDeflate(json);
614
+
615
+ this.enhancedDebug(`Publishing profile to MQTT`);
616
+ const result = await mqtt.publish({
617
+ topic: constants_1.Topics.SEND_MESSAGE.id,
618
+ qosLevel: 1,
619
+ payload: payload,
620
+ });
621
+
622
+ this.enhancedDebug(`✅ Profile sent via MQTT!`);
623
+ return result;
624
+ } catch (err) {
625
+ this.enhancedDebug(`Profile send failed: ${err.message}`);
626
+ throw err;
627
+ }
628
+ }
629
+
630
+ /**
631
+ * Send hashtag via MQTT
632
+ */
633
+ async sendHashtag({ text, hashtag, threadId, clientContext }) {
634
+ this.enhancedDebug(`Sending hashtag ${hashtag} to ${threadId} via MQTT`);
635
+
636
+ try {
637
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
638
+ if (!mqtt || typeof mqtt.publish !== 'function') {
639
+ throw new Error('MQTT client not available');
640
+ }
641
+
642
+ const ctx = clientContext || (0, uuid_1.v4)();
643
+ const command = {
644
+ action: 'send_item',
645
+ thread_id: threadId,
646
+ item_type: 'hashtag',
647
+ hashtag: hashtag,
648
+ text: text || '',
649
+ timestamp: Date.now(),
650
+ client_context: ctx,
651
+ };
652
+
653
+ const json = JSON.stringify(command);
654
+ const { compressDeflate } = shared_1;
655
+ const payload = await compressDeflate(json);
656
+
657
+ this.enhancedDebug(`Publishing hashtag to MQTT`);
658
+ const result = await mqtt.publish({
659
+ topic: constants_1.Topics.SEND_MESSAGE.id,
660
+ qosLevel: 1,
661
+ payload: payload,
662
+ });
663
+
664
+ this.enhancedDebug(`✅ Hashtag sent via MQTT!`);
665
+ return result;
666
+ } catch (err) {
667
+ this.enhancedDebug(`Hashtag send failed: ${err.message}`);
668
+ throw err;
669
+ }
670
+ }
671
+
672
+ /**
673
+ * Send like via MQTT
674
+ */
675
+ async sendLike({ threadId, clientContext }) {
676
+ this.enhancedDebug(`Sending like in thread ${threadId} via MQTT`);
677
+
678
+ try {
679
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
680
+ if (!mqtt || typeof mqtt.publish !== 'function') {
681
+ throw new Error('MQTT client not available');
682
+ }
683
+
684
+ const ctx = clientContext || (0, uuid_1.v4)();
685
+ const command = {
686
+ action: 'send_item',
687
+ thread_id: threadId,
688
+ item_type: 'like',
689
+ timestamp: Date.now(),
690
+ client_context: ctx,
691
+ };
692
+
693
+ const json = JSON.stringify(command);
694
+ const { compressDeflate } = shared_1;
695
+ const payload = await compressDeflate(json);
696
+
697
+ this.enhancedDebug(`Publishing like to MQTT`);
698
+ const result = await mqtt.publish({
699
+ topic: constants_1.Topics.SEND_MESSAGE.id,
700
+ qosLevel: 1,
701
+ payload: payload,
702
+ });
703
+
704
+ this.enhancedDebug(`✅ Like sent via MQTT!`);
705
+ return result;
706
+ } catch (err) {
707
+ this.enhancedDebug(`Like send failed: ${err.message}`);
708
+ throw err;
709
+ }
710
+ }
711
+
712
+ /**
713
+ * Send user story via MQTT
714
+ */
715
+ async sendUserStory({ text, storyId, threadId, clientContext }) {
716
+ this.enhancedDebug(`Sending story ${storyId} to ${threadId} via MQTT`);
717
+
718
+ try {
719
+ const mqtt = this.realtimeClient.mqtt || this.realtimeClient._mqtt;
720
+ if (!mqtt || typeof mqtt.publish !== 'function') {
721
+ throw new Error('MQTT client not available');
722
+ }
723
+
724
+ const ctx = clientContext || (0, uuid_1.v4)();
725
+ const command = {
726
+ action: 'send_item',
727
+ thread_id: threadId,
728
+ item_type: 'story',
729
+ story_id: storyId,
730
+ text: text || '',
731
+ timestamp: Date.now(),
732
+ client_context: ctx,
733
+ };
734
+
735
+ const json = JSON.stringify(command);
736
+ const { compressDeflate } = shared_1;
737
+ const payload = await compressDeflate(json);
738
+
739
+ this.enhancedDebug(`Publishing story to MQTT`);
740
+ const result = await mqtt.publish({
741
+ topic: constants_1.Topics.SEND_MESSAGE.id,
742
+ qosLevel: 1,
743
+ payload: payload,
744
+ });
745
+
746
+ this.enhancedDebug(`✅ Story sent via MQTT!`);
747
+ return result;
748
+ } catch (err) {
749
+ this.enhancedDebug(`Story send failed: ${err.message}`);
750
+ throw err;
751
+ }
752
+ }
753
+
754
+ /**
755
+ * Send photo via Realtime (Upload + Broadcast)
756
+ * This method uploads the photo first, then broadcasts it to the thread
757
+ *
758
+ * @param {Object} options - Photo sending options
759
+ * @param {Buffer} options.photoBuffer - Image buffer (JPEG/PNG)
760
+ * @param {string} options.threadId - Thread ID to send to
761
+ * @param {string} [options.caption] - Optional caption
762
+ * @param {string} [options.mimeType='image/jpeg'] - MIME type
763
+ * @param {string} [options.clientContext] - Optional client context
764
+ */
765
+ async sendPhotoViaRealtime({ photoBuffer, threadId, caption = '', mimeType = 'image/jpeg', clientContext }) {
766
+ this.enhancedDebug(`Sending photo to thread ${threadId} via Realtime`);
767
+
768
+ try {
769
+ // Validate inputs
770
+ if (!photoBuffer || !Buffer.isBuffer(photoBuffer) || photoBuffer.length === 0) {
771
+ throw new Error('photoBuffer must be a non-empty Buffer');
772
+ }
773
+ if (!threadId) {
774
+ throw new Error('threadId is required');
775
+ }
776
+
777
+ // Get the ig client from realtime client
778
+ const ig = this.realtimeClient.ig;
779
+ if (!ig || !ig.request) {
780
+ throw new Error('Instagram client not available. Make sure you are logged in.');
781
+ }
782
+
783
+ // Step 1: Upload photo using rupload endpoint
784
+ this.enhancedDebug(`Step 1: Uploading photo (${photoBuffer.length} bytes)...`);
785
+
786
+ const uploadId = Date.now().toString();
787
+ const objectName = `${(0, uuid_1.v4)()}.${mimeType === 'image/png' ? 'png' : 'jpg'}`;
788
+
789
+ const isJpeg = mimeType === 'image/jpeg' || mimeType === 'image/jpg';
790
+ const compression = isJpeg
791
+ ? '{"lib_name":"moz","lib_version":"3.1.m","quality":"80"}'
792
+ : '{"lib_name":"png","lib_version":"1.0","quality":"100"}';
793
+
794
+ const ruploadParams = {
795
+ upload_id: uploadId,
796
+ media_type: 1,
797
+ image_compression: compression,
798
+ xsharing_user_ids: JSON.stringify([]),
799
+ is_clips_media: false,
800
+ };
801
+
802
+ const uploadHeaders = {
803
+ 'X-Instagram-Rupload-Params': JSON.stringify(ruploadParams),
804
+ 'Content-Type': mimeType,
805
+ 'X_FB_PHOTO_WATERFALL_ID': (0, uuid_1.v4)(),
806
+ 'X-Entity-Type': mimeType,
807
+ 'X-Entity-Length': String(photoBuffer.length),
808
+ 'Content-Length': String(photoBuffer.length),
809
+ };
810
+
811
+ const uploadUrl = `/rupload_igphoto/${objectName}`;
812
+
813
+ let serverUploadId = uploadId;
814
+ try {
815
+ const uploadResponse = await ig.request.send({
816
+ url: uploadUrl,
817
+ method: 'POST',
818
+ headers: uploadHeaders,
819
+ body: photoBuffer,
820
+ });
821
+
822
+ if (uploadResponse && typeof uploadResponse === 'object' && uploadResponse.upload_id) {
823
+ serverUploadId = uploadResponse.upload_id;
824
+ }
825
+ this.enhancedDebug(`✅ Photo uploaded! upload_id: ${serverUploadId}`);
826
+ } catch (uploadErr) {
827
+ this.enhancedDebug(`Upload error: ${uploadErr.message}`);
828
+ throw new Error(`Photo upload failed: ${uploadErr.message}`);
829
+ }
830
+
831
+ // Step 2: Broadcast the uploaded photo to the thread
832
+ this.enhancedDebug(`Step 2: Broadcasting photo to thread ${threadId}...`);
833
+
834
+ const broadcastForm = {
835
+ upload_id: serverUploadId,
836
+ action: 'send_item',
837
+ thread_ids: JSON.stringify([String(threadId)]),
838
+ };
839
+
840
+ if (caption) {
841
+ broadcastForm.caption = caption;
842
+ }
843
+
844
+ try {
845
+ const broadcastResponse = await ig.request.send({
846
+ url: '/direct_v2/threads/broadcast/upload_photo/',
847
+ method: 'POST',
848
+ form: broadcastForm,
849
+ });
850
+
851
+ this.enhancedDebug(`✅ Photo sent successfully to thread ${threadId}!`);
852
+ return broadcastResponse;
853
+ } catch (broadcastErr) {
854
+ this.enhancedDebug(`Broadcast error: ${broadcastErr.message}`);
855
+ throw new Error(`Photo broadcast failed: ${broadcastErr.message}`);
856
+ }
857
+
858
+ } catch (err) {
859
+ this.enhancedDebug(`sendPhotoViaRealtime failed: ${err.message}`);
860
+ throw err;
861
+ }
862
+ }
863
+
864
+ /**
865
+ * Alias for sendPhotoViaRealtime (for compatibility)
866
+ */
867
+ async sendPhoto(options) {
868
+ return this.sendPhotoViaRealtime(options);
869
+ }
870
+
871
+ /**
872
+ * Send video via Realtime (Upload + Broadcast)
873
+ *
874
+ * @param {Object} options - Video sending options
875
+ * @param {Buffer} options.videoBuffer - Video buffer (MP4)
876
+ * @param {string} options.threadId - Thread ID to send to
877
+ * @param {string} [options.caption] - Optional caption
878
+ * @param {number} [options.duration] - Video duration in seconds
879
+ * @param {number} [options.width] - Video width
880
+ * @param {number} [options.height] - Video height
881
+ * @param {string} [options.clientContext] - Optional client context
882
+ */
883
+ async sendVideoViaRealtime({ videoBuffer, threadId, caption = '', duration = 0, width = 720, height = 1280, clientContext }) {
884
+ this.enhancedDebug(`Sending video to thread ${threadId} via Realtime`);
885
+
886
+ try {
887
+ // Validate inputs
888
+ if (!videoBuffer || !Buffer.isBuffer(videoBuffer) || videoBuffer.length === 0) {
889
+ throw new Error('videoBuffer must be a non-empty Buffer');
890
+ }
891
+ if (!threadId) {
892
+ throw new Error('threadId is required');
893
+ }
894
+
895
+ // Get the ig client from realtime client
896
+ const ig = this.realtimeClient.ig;
897
+ if (!ig || !ig.request) {
898
+ throw new Error('Instagram client not available. Make sure you are logged in.');
899
+ }
900
+
901
+ // Step 1: Upload video using rupload endpoint
902
+ this.enhancedDebug(`Step 1: Uploading video (${videoBuffer.length} bytes)...`);
903
+
904
+ const uploadId = Date.now().toString();
905
+ const objectName = `${(0, uuid_1.v4)()}.mp4`;
906
+
907
+ const ruploadParams = {
908
+ upload_id: uploadId,
909
+ media_type: 2, // 2 = video
910
+ xsharing_user_ids: JSON.stringify([]),
911
+ upload_media_duration_ms: Math.round(duration * 1000),
912
+ upload_media_width: width,
913
+ upload_media_height: height,
914
+ };
915
+
916
+ const uploadHeaders = {
917
+ 'X-Instagram-Rupload-Params': JSON.stringify(ruploadParams),
918
+ 'Content-Type': 'video/mp4',
919
+ 'X_FB_VIDEO_WATERFALL_ID': (0, uuid_1.v4)(),
920
+ 'X-Entity-Type': 'video/mp4',
921
+ 'X-Entity-Length': String(videoBuffer.length),
922
+ 'Content-Length': String(videoBuffer.length),
923
+ 'Offset': '0',
924
+ };
925
+
926
+ const uploadUrl = `/rupload_igvideo/${objectName}`;
927
+
928
+ let serverUploadId = uploadId;
929
+ try {
930
+ const uploadResponse = await ig.request.send({
931
+ url: uploadUrl,
932
+ method: 'POST',
933
+ headers: uploadHeaders,
934
+ body: videoBuffer,
935
+ });
936
+
937
+ if (uploadResponse && typeof uploadResponse === 'object' && uploadResponse.upload_id) {
938
+ serverUploadId = uploadResponse.upload_id;
939
+ }
940
+ this.enhancedDebug(`✅ Video uploaded! upload_id: ${serverUploadId}`);
941
+ } catch (uploadErr) {
942
+ this.enhancedDebug(`Video upload error: ${uploadErr.message}`);
943
+ throw new Error(`Video upload failed: ${uploadErr.message}`);
944
+ }
945
+
946
+ // Step 2: Broadcast the uploaded video to the thread
947
+ this.enhancedDebug(`Step 2: Broadcasting video to thread ${threadId}...`);
948
+
949
+ const broadcastForm = {
950
+ upload_id: serverUploadId,
951
+ action: 'send_item',
952
+ thread_ids: JSON.stringify([String(threadId)]),
953
+ video_result: '',
954
+ };
955
+
956
+ if (caption) {
957
+ broadcastForm.caption = caption;
958
+ }
959
+
960
+ try {
961
+ const broadcastResponse = await ig.request.send({
962
+ url: '/direct_v2/threads/broadcast/upload_video/',
963
+ method: 'POST',
964
+ form: broadcastForm,
965
+ });
966
+
967
+ this.enhancedDebug(`✅ Video sent successfully to thread ${threadId}!`);
968
+ return broadcastResponse;
969
+ } catch (broadcastErr) {
970
+ this.enhancedDebug(`Video broadcast error: ${broadcastErr.message}`);
971
+ throw new Error(`Video broadcast failed: ${broadcastErr.message}`);
972
+ }
973
+
974
+ } catch (err) {
975
+ this.enhancedDebug(`sendVideoViaRealtime failed: ${err.message}`);
976
+ throw err;
977
+ }
978
+ }
979
+
980
+ /**
981
+ * Alias for sendVideoViaRealtime (for compatibility)
982
+ */
983
+ async sendVideo(options) {
984
+ return this.sendVideoViaRealtime(options);
985
+ }
986
+ }
987
+ exports.EnhancedDirectCommands = EnhancedDirectCommands;