nodejs-insta-private-api-mqtt 1.3.28 → 1.3.30
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.
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EnhancedDirectCommands = void 0;
|
|
4
4
|
const shared_1 = require("../../shared");
|
|
5
|
-
const
|
|
5
|
+
const uuid_1 = require("uuid");
|
|
6
6
|
const constants_1 = require("../../constants");
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -14,27 +14,10 @@ class EnhancedDirectCommands {
|
|
|
14
14
|
this.enhancedDebug = (0, shared_1.debugChannel)('realtime', 'enhanced-commands');
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
/**
|
|
18
|
-
* Get or create persistent client_context for the session.
|
|
19
|
-
* If caller provided clientContext param, that is used instead.
|
|
20
|
-
*/
|
|
21
|
-
_getClientContext(provided) {
|
|
22
|
-
if (provided) return provided;
|
|
23
|
-
if (!this.realtimeClient) return uuidv4();
|
|
24
|
-
if (!this.realtimeClient._clientContext) {
|
|
25
|
-
try {
|
|
26
|
-
this.realtimeClient._clientContext = uuidv4();
|
|
27
|
-
} catch (e) {
|
|
28
|
-
this.realtimeClient._clientContext = `cc_${Date.now()}`;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return this.realtimeClient._clientContext;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
17
|
/**
|
|
35
18
|
* Send text via MQTT with proper payload format
|
|
36
19
|
*/
|
|
37
|
-
async sendTextViaRealtime(threadId, text
|
|
20
|
+
async sendTextViaRealtime(threadId, text) {
|
|
38
21
|
this.enhancedDebug(`Sending text to ${threadId}: "${text}"`);
|
|
39
22
|
|
|
40
23
|
try {
|
|
@@ -44,32 +27,33 @@ class EnhancedDirectCommands {
|
|
|
44
27
|
}
|
|
45
28
|
|
|
46
29
|
// Build proper command payload
|
|
47
|
-
const
|
|
30
|
+
const clientContext = (0, uuid_1.v4)();
|
|
48
31
|
const command = {
|
|
49
32
|
action: 'send_item',
|
|
50
|
-
thread_id:
|
|
33
|
+
thread_id: threadId,
|
|
51
34
|
item_type: 'text',
|
|
52
|
-
text:
|
|
35
|
+
text: text,
|
|
53
36
|
timestamp: Date.now(),
|
|
54
|
-
client_context:
|
|
37
|
+
client_context: clientContext,
|
|
55
38
|
};
|
|
56
39
|
|
|
57
40
|
// Compress JSON payload
|
|
58
41
|
const json = JSON.stringify(command);
|
|
59
|
-
const
|
|
42
|
+
const { compressDeflate } = shared_1;
|
|
43
|
+
const payload = await compressDeflate(json);
|
|
60
44
|
|
|
61
|
-
// Send to MQTT
|
|
45
|
+
// Send to MQTT
|
|
62
46
|
this.enhancedDebug(`Publishing to MQTT topic ${constants_1.Topics.SEND_MESSAGE.id}`);
|
|
63
47
|
const result = await mqtt.publish({
|
|
64
48
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
65
|
-
qosLevel:
|
|
49
|
+
qosLevel: 1,
|
|
66
50
|
payload: payload,
|
|
67
51
|
});
|
|
68
52
|
|
|
69
53
|
this.enhancedDebug(`✅ Message sent via MQTT!`);
|
|
70
54
|
return result;
|
|
71
55
|
} catch (err) {
|
|
72
|
-
this.enhancedDebug(`Failed: ${err
|
|
56
|
+
this.enhancedDebug(`Failed: ${err.message}`);
|
|
73
57
|
throw err;
|
|
74
58
|
}
|
|
75
59
|
}
|
|
@@ -77,7 +61,7 @@ class EnhancedDirectCommands {
|
|
|
77
61
|
/**
|
|
78
62
|
* Delete message via MQTT
|
|
79
63
|
*/
|
|
80
|
-
async deleteMessage(threadId, itemId
|
|
64
|
+
async deleteMessage(threadId, itemId) {
|
|
81
65
|
this.enhancedDebug(`Deleting message ${itemId} from thread ${threadId}`);
|
|
82
66
|
|
|
83
67
|
try {
|
|
@@ -86,29 +70,30 @@ class EnhancedDirectCommands {
|
|
|
86
70
|
throw new Error('MQTT client not available');
|
|
87
71
|
}
|
|
88
72
|
|
|
89
|
-
const
|
|
73
|
+
const clientContext = (0, uuid_1.v4)();
|
|
90
74
|
const command = {
|
|
91
75
|
action: 'delete_item',
|
|
92
|
-
thread_id:
|
|
93
|
-
item_id:
|
|
76
|
+
thread_id: threadId,
|
|
77
|
+
item_id: itemId,
|
|
94
78
|
timestamp: Date.now(),
|
|
95
|
-
client_context:
|
|
79
|
+
client_context: clientContext,
|
|
96
80
|
};
|
|
97
81
|
|
|
98
82
|
const json = JSON.stringify(command);
|
|
99
|
-
const
|
|
83
|
+
const { compressDeflate } = shared_1;
|
|
84
|
+
const payload = await compressDeflate(json);
|
|
100
85
|
|
|
101
86
|
this.enhancedDebug(`Publishing delete command to MQTT topic ${constants_1.Topics.SEND_MESSAGE.id}`);
|
|
102
87
|
const result = await mqtt.publish({
|
|
103
88
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
104
|
-
qosLevel:
|
|
89
|
+
qosLevel: 1,
|
|
105
90
|
payload: payload,
|
|
106
91
|
});
|
|
107
92
|
|
|
108
93
|
this.enhancedDebug(`✅ Message deleted via MQTT!`);
|
|
109
94
|
return result;
|
|
110
95
|
} catch (err) {
|
|
111
|
-
this.enhancedDebug(`Delete failed: ${err
|
|
96
|
+
this.enhancedDebug(`Delete failed: ${err.message}`);
|
|
112
97
|
throw err;
|
|
113
98
|
}
|
|
114
99
|
}
|
|
@@ -116,7 +101,7 @@ class EnhancedDirectCommands {
|
|
|
116
101
|
/**
|
|
117
102
|
* Edit message via MQTT
|
|
118
103
|
*/
|
|
119
|
-
async editMessage(threadId, itemId, newText
|
|
104
|
+
async editMessage(threadId, itemId, newText) {
|
|
120
105
|
this.enhancedDebug(`Editing message ${itemId}: "${newText}"`);
|
|
121
106
|
|
|
122
107
|
try {
|
|
@@ -125,30 +110,31 @@ class EnhancedDirectCommands {
|
|
|
125
110
|
throw new Error('MQTT client not available');
|
|
126
111
|
}
|
|
127
112
|
|
|
128
|
-
const
|
|
113
|
+
const clientContext = (0, uuid_1.v4)();
|
|
129
114
|
const command = {
|
|
130
115
|
action: 'edit_item',
|
|
131
|
-
thread_id:
|
|
132
|
-
item_id:
|
|
133
|
-
text:
|
|
116
|
+
thread_id: threadId,
|
|
117
|
+
item_id: itemId,
|
|
118
|
+
text: newText,
|
|
134
119
|
timestamp: Date.now(),
|
|
135
|
-
client_context:
|
|
120
|
+
client_context: clientContext,
|
|
136
121
|
};
|
|
137
122
|
|
|
138
123
|
const json = JSON.stringify(command);
|
|
139
|
-
const
|
|
124
|
+
const { compressDeflate } = shared_1;
|
|
125
|
+
const payload = await compressDeflate(json);
|
|
140
126
|
|
|
141
127
|
this.enhancedDebug(`Publishing edit command to MQTT topic ${constants_1.Topics.SEND_MESSAGE.id}`);
|
|
142
128
|
const result = await mqtt.publish({
|
|
143
129
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
144
|
-
qosLevel:
|
|
130
|
+
qosLevel: 1,
|
|
145
131
|
payload: payload,
|
|
146
132
|
});
|
|
147
133
|
|
|
148
134
|
this.enhancedDebug(`✅ Message edited via MQTT!`);
|
|
149
135
|
return result;
|
|
150
136
|
} catch (err) {
|
|
151
|
-
this.enhancedDebug(`Edit failed: ${err
|
|
137
|
+
this.enhancedDebug(`Edit failed: ${err.message}`);
|
|
152
138
|
throw err;
|
|
153
139
|
}
|
|
154
140
|
}
|
|
@@ -156,7 +142,7 @@ class EnhancedDirectCommands {
|
|
|
156
142
|
/**
|
|
157
143
|
* Reply to message via MQTT (Quote Reply)
|
|
158
144
|
*/
|
|
159
|
-
async replyToMessage(threadId, messageId, replyText
|
|
145
|
+
async replyToMessage(threadId, messageId, replyText) {
|
|
160
146
|
this.enhancedDebug(`Replying to ${messageId} in thread ${threadId}: "${replyText}"`);
|
|
161
147
|
|
|
162
148
|
try {
|
|
@@ -165,31 +151,32 @@ class EnhancedDirectCommands {
|
|
|
165
151
|
throw new Error('MQTT client not available');
|
|
166
152
|
}
|
|
167
153
|
|
|
168
|
-
const
|
|
154
|
+
const clientContext = (0, uuid_1.v4)();
|
|
169
155
|
const command = {
|
|
170
156
|
action: 'send_item',
|
|
171
|
-
thread_id:
|
|
157
|
+
thread_id: threadId,
|
|
172
158
|
item_type: 'text',
|
|
173
|
-
text:
|
|
174
|
-
replying_to_item_id:
|
|
159
|
+
text: replyText,
|
|
160
|
+
replying_to_item_id: messageId,
|
|
175
161
|
timestamp: Date.now(),
|
|
176
|
-
client_context:
|
|
162
|
+
client_context: clientContext,
|
|
177
163
|
};
|
|
178
164
|
|
|
179
165
|
const json = JSON.stringify(command);
|
|
180
|
-
const
|
|
166
|
+
const { compressDeflate } = shared_1;
|
|
167
|
+
const payload = await compressDeflate(json);
|
|
181
168
|
|
|
182
169
|
this.enhancedDebug(`Publishing reply command to MQTT topic ${constants_1.Topics.SEND_MESSAGE.id}`);
|
|
183
170
|
const result = await mqtt.publish({
|
|
184
171
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
185
|
-
qosLevel:
|
|
172
|
+
qosLevel: 1,
|
|
186
173
|
payload: payload,
|
|
187
174
|
});
|
|
188
175
|
|
|
189
176
|
this.enhancedDebug(`✅ Reply sent via MQTT!`);
|
|
190
177
|
return result;
|
|
191
178
|
} catch (err) {
|
|
192
|
-
this.enhancedDebug(`Reply failed: ${err
|
|
179
|
+
this.enhancedDebug(`Reply failed: ${err.message}`);
|
|
193
180
|
throw err;
|
|
194
181
|
}
|
|
195
182
|
}
|
|
@@ -197,7 +184,7 @@ class EnhancedDirectCommands {
|
|
|
197
184
|
/**
|
|
198
185
|
* Subscribe to follow notifications via MQTT
|
|
199
186
|
*/
|
|
200
|
-
async subscribeToFollowNotifications(
|
|
187
|
+
async subscribeToFollowNotifications() {
|
|
201
188
|
this.enhancedDebug(`Subscribing to follow notifications via MQTT`);
|
|
202
189
|
|
|
203
190
|
try {
|
|
@@ -206,28 +193,29 @@ class EnhancedDirectCommands {
|
|
|
206
193
|
throw new Error('MQTT client not available');
|
|
207
194
|
}
|
|
208
195
|
|
|
209
|
-
const
|
|
196
|
+
const clientContext = (0, uuid_1.v4)();
|
|
210
197
|
const command = {
|
|
211
198
|
action: 'subscribe',
|
|
212
199
|
subscription_type: 'follow_notifications',
|
|
213
200
|
timestamp: Date.now(),
|
|
214
|
-
client_context:
|
|
201
|
+
client_context: clientContext,
|
|
215
202
|
};
|
|
216
203
|
|
|
217
204
|
const json = JSON.stringify(command);
|
|
218
|
-
const
|
|
205
|
+
const { compressDeflate } = shared_1;
|
|
206
|
+
const payload = await compressDeflate(json);
|
|
219
207
|
|
|
220
208
|
this.enhancedDebug(`Publishing follow subscription to MQTT`);
|
|
221
209
|
const result = await mqtt.publish({
|
|
222
210
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
223
|
-
qosLevel:
|
|
211
|
+
qosLevel: 1,
|
|
224
212
|
payload: payload,
|
|
225
213
|
});
|
|
226
214
|
|
|
227
215
|
this.enhancedDebug(`✅ Follow notifications subscribed via MQTT!`);
|
|
228
216
|
return result;
|
|
229
217
|
} catch (err) {
|
|
230
|
-
this.enhancedDebug(`Follow subscription failed: ${err
|
|
218
|
+
this.enhancedDebug(`Follow subscription failed: ${err.message}`);
|
|
231
219
|
throw err;
|
|
232
220
|
}
|
|
233
221
|
}
|
|
@@ -235,7 +223,7 @@ class EnhancedDirectCommands {
|
|
|
235
223
|
/**
|
|
236
224
|
* Subscribe to mention notifications via MQTT
|
|
237
225
|
*/
|
|
238
|
-
async subscribeToMentionNotifications(
|
|
226
|
+
async subscribeToMentionNotifications() {
|
|
239
227
|
this.enhancedDebug(`Subscribing to mention notifications via MQTT`);
|
|
240
228
|
|
|
241
229
|
try {
|
|
@@ -244,28 +232,29 @@ class EnhancedDirectCommands {
|
|
|
244
232
|
throw new Error('MQTT client not available');
|
|
245
233
|
}
|
|
246
234
|
|
|
247
|
-
const
|
|
235
|
+
const clientContext = (0, uuid_1.v4)();
|
|
248
236
|
const command = {
|
|
249
237
|
action: 'subscribe',
|
|
250
238
|
subscription_type: 'mention_notifications',
|
|
251
239
|
timestamp: Date.now(),
|
|
252
|
-
client_context:
|
|
240
|
+
client_context: clientContext,
|
|
253
241
|
};
|
|
254
242
|
|
|
255
243
|
const json = JSON.stringify(command);
|
|
256
|
-
const
|
|
244
|
+
const { compressDeflate } = shared_1;
|
|
245
|
+
const payload = await compressDeflate(json);
|
|
257
246
|
|
|
258
247
|
this.enhancedDebug(`Publishing mention subscription to MQTT`);
|
|
259
248
|
const result = await mqtt.publish({
|
|
260
249
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
261
|
-
qosLevel:
|
|
250
|
+
qosLevel: 1,
|
|
262
251
|
payload: payload,
|
|
263
252
|
});
|
|
264
253
|
|
|
265
254
|
this.enhancedDebug(`✅ Mention notifications subscribed via MQTT!`);
|
|
266
255
|
return result;
|
|
267
256
|
} catch (err) {
|
|
268
|
-
this.enhancedDebug(`Mention subscription failed: ${err
|
|
257
|
+
this.enhancedDebug(`Mention subscription failed: ${err.message}`);
|
|
269
258
|
throw err;
|
|
270
259
|
}
|
|
271
260
|
}
|
|
@@ -273,7 +262,7 @@ class EnhancedDirectCommands {
|
|
|
273
262
|
/**
|
|
274
263
|
* Subscribe to call notifications via MQTT
|
|
275
264
|
*/
|
|
276
|
-
async subscribeToCallNotifications(
|
|
265
|
+
async subscribeToCallNotifications() {
|
|
277
266
|
this.enhancedDebug(`Subscribing to call notifications via MQTT`);
|
|
278
267
|
|
|
279
268
|
try {
|
|
@@ -282,28 +271,29 @@ class EnhancedDirectCommands {
|
|
|
282
271
|
throw new Error('MQTT client not available');
|
|
283
272
|
}
|
|
284
273
|
|
|
285
|
-
const
|
|
274
|
+
const clientContext = (0, uuid_1.v4)();
|
|
286
275
|
const command = {
|
|
287
276
|
action: 'subscribe',
|
|
288
277
|
subscription_type: 'call_notifications',
|
|
289
278
|
timestamp: Date.now(),
|
|
290
|
-
client_context:
|
|
279
|
+
client_context: clientContext,
|
|
291
280
|
};
|
|
292
281
|
|
|
293
282
|
const json = JSON.stringify(command);
|
|
294
|
-
const
|
|
283
|
+
const { compressDeflate } = shared_1;
|
|
284
|
+
const payload = await compressDeflate(json);
|
|
295
285
|
|
|
296
286
|
this.enhancedDebug(`Publishing call subscription to MQTT`);
|
|
297
287
|
const result = await mqtt.publish({
|
|
298
288
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
299
|
-
qosLevel:
|
|
289
|
+
qosLevel: 1,
|
|
300
290
|
payload: payload,
|
|
301
291
|
});
|
|
302
292
|
|
|
303
293
|
this.enhancedDebug(`✅ Call notifications subscribed via MQTT!`);
|
|
304
294
|
return result;
|
|
305
295
|
} catch (err) {
|
|
306
|
-
this.enhancedDebug(`Call subscription failed: ${err
|
|
296
|
+
this.enhancedDebug(`Call subscription failed: ${err.message}`);
|
|
307
297
|
throw err;
|
|
308
298
|
}
|
|
309
299
|
}
|
|
@@ -311,7 +301,7 @@ class EnhancedDirectCommands {
|
|
|
311
301
|
/**
|
|
312
302
|
* Add member to thread via MQTT
|
|
313
303
|
*/
|
|
314
|
-
async addMemberToThread(threadId, userId
|
|
304
|
+
async addMemberToThread(threadId, userId) {
|
|
315
305
|
this.enhancedDebug(`Adding user ${userId} to thread ${threadId} via MQTT`);
|
|
316
306
|
|
|
317
307
|
try {
|
|
@@ -320,29 +310,30 @@ class EnhancedDirectCommands {
|
|
|
320
310
|
throw new Error('MQTT client not available');
|
|
321
311
|
}
|
|
322
312
|
|
|
323
|
-
const
|
|
313
|
+
const clientContext = (0, uuid_1.v4)();
|
|
324
314
|
const command = {
|
|
325
315
|
action: 'add_member',
|
|
326
|
-
thread_id:
|
|
327
|
-
user_id:
|
|
316
|
+
thread_id: threadId,
|
|
317
|
+
user_id: userId,
|
|
328
318
|
timestamp: Date.now(),
|
|
329
|
-
client_context:
|
|
319
|
+
client_context: clientContext,
|
|
330
320
|
};
|
|
331
321
|
|
|
332
322
|
const json = JSON.stringify(command);
|
|
333
|
-
const
|
|
323
|
+
const { compressDeflate } = shared_1;
|
|
324
|
+
const payload = await compressDeflate(json);
|
|
334
325
|
|
|
335
326
|
this.enhancedDebug(`Publishing add member command to MQTT`);
|
|
336
327
|
const result = await mqtt.publish({
|
|
337
328
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
338
|
-
qosLevel:
|
|
329
|
+
qosLevel: 1,
|
|
339
330
|
payload: payload,
|
|
340
331
|
});
|
|
341
332
|
|
|
342
333
|
this.enhancedDebug(`✅ Member added to thread via MQTT!`);
|
|
343
334
|
return result;
|
|
344
335
|
} catch (err) {
|
|
345
|
-
this.enhancedDebug(`Add member failed: ${err
|
|
336
|
+
this.enhancedDebug(`Add member failed: ${err.message}`);
|
|
346
337
|
throw err;
|
|
347
338
|
}
|
|
348
339
|
}
|
|
@@ -350,7 +341,7 @@ class EnhancedDirectCommands {
|
|
|
350
341
|
/**
|
|
351
342
|
* Remove member from thread via MQTT
|
|
352
343
|
*/
|
|
353
|
-
async removeMemberFromThread(threadId, userId
|
|
344
|
+
async removeMemberFromThread(threadId, userId) {
|
|
354
345
|
this.enhancedDebug(`Removing user ${userId} from thread ${threadId} via MQTT`);
|
|
355
346
|
|
|
356
347
|
try {
|
|
@@ -359,29 +350,30 @@ class EnhancedDirectCommands {
|
|
|
359
350
|
throw new Error('MQTT client not available');
|
|
360
351
|
}
|
|
361
352
|
|
|
362
|
-
const
|
|
353
|
+
const clientContext = (0, uuid_1.v4)();
|
|
363
354
|
const command = {
|
|
364
355
|
action: 'remove_member',
|
|
365
|
-
thread_id:
|
|
366
|
-
user_id:
|
|
356
|
+
thread_id: threadId,
|
|
357
|
+
user_id: userId,
|
|
367
358
|
timestamp: Date.now(),
|
|
368
|
-
client_context:
|
|
359
|
+
client_context: clientContext,
|
|
369
360
|
};
|
|
370
361
|
|
|
371
362
|
const json = JSON.stringify(command);
|
|
372
|
-
const
|
|
363
|
+
const { compressDeflate } = shared_1;
|
|
364
|
+
const payload = await compressDeflate(json);
|
|
373
365
|
|
|
374
366
|
this.enhancedDebug(`Publishing remove member command to MQTT`);
|
|
375
367
|
const result = await mqtt.publish({
|
|
376
368
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
377
|
-
qosLevel:
|
|
369
|
+
qosLevel: 1,
|
|
378
370
|
payload: payload,
|
|
379
371
|
});
|
|
380
372
|
|
|
381
373
|
this.enhancedDebug(`✅ Member removed from thread via MQTT!`);
|
|
382
374
|
return result;
|
|
383
375
|
} catch (err) {
|
|
384
|
-
this.enhancedDebug(`Remove member failed: ${err
|
|
376
|
+
this.enhancedDebug(`Remove member failed: ${err.message}`);
|
|
385
377
|
throw err;
|
|
386
378
|
}
|
|
387
379
|
}
|
|
@@ -398,11 +390,11 @@ class EnhancedDirectCommands {
|
|
|
398
390
|
throw new Error('MQTT client not available');
|
|
399
391
|
}
|
|
400
392
|
|
|
401
|
-
const ctx =
|
|
393
|
+
const ctx = clientContext || (0, uuid_1.v4)();
|
|
402
394
|
const command = {
|
|
403
395
|
action: 'send_reaction',
|
|
404
|
-
thread_id:
|
|
405
|
-
item_id:
|
|
396
|
+
thread_id: threadId,
|
|
397
|
+
item_id: itemId,
|
|
406
398
|
reaction_type: reactionType,
|
|
407
399
|
reaction_status: reactionStatus,
|
|
408
400
|
emoji: emoji || '',
|
|
@@ -411,19 +403,20 @@ class EnhancedDirectCommands {
|
|
|
411
403
|
};
|
|
412
404
|
|
|
413
405
|
const json = JSON.stringify(command);
|
|
414
|
-
const
|
|
406
|
+
const { compressDeflate } = shared_1;
|
|
407
|
+
const payload = await compressDeflate(json);
|
|
415
408
|
|
|
416
409
|
this.enhancedDebug(`Publishing reaction to MQTT`);
|
|
417
410
|
const result = await mqtt.publish({
|
|
418
411
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
419
|
-
qosLevel:
|
|
412
|
+
qosLevel: 1,
|
|
420
413
|
payload: payload,
|
|
421
414
|
});
|
|
422
415
|
|
|
423
416
|
this.enhancedDebug(`✅ Reaction sent via MQTT!`);
|
|
424
417
|
return result;
|
|
425
418
|
} catch (err) {
|
|
426
|
-
this.enhancedDebug(`Reaction failed: ${err
|
|
419
|
+
this.enhancedDebug(`Reaction failed: ${err.message}`);
|
|
427
420
|
throw err;
|
|
428
421
|
}
|
|
429
422
|
}
|
|
@@ -431,7 +424,7 @@ class EnhancedDirectCommands {
|
|
|
431
424
|
/**
|
|
432
425
|
* Mark message as seen via MQTT
|
|
433
426
|
*/
|
|
434
|
-
async markAsSeen({ threadId, itemId
|
|
427
|
+
async markAsSeen({ threadId, itemId }) {
|
|
435
428
|
this.enhancedDebug(`Marking message ${itemId} as seen in thread ${threadId} via MQTT`);
|
|
436
429
|
|
|
437
430
|
try {
|
|
@@ -440,29 +433,30 @@ class EnhancedDirectCommands {
|
|
|
440
433
|
throw new Error('MQTT client not available');
|
|
441
434
|
}
|
|
442
435
|
|
|
443
|
-
const
|
|
436
|
+
const clientContext = (0, uuid_1.v4)();
|
|
444
437
|
const command = {
|
|
445
438
|
action: 'mark_as_seen',
|
|
446
|
-
thread_id:
|
|
447
|
-
item_id:
|
|
439
|
+
thread_id: threadId,
|
|
440
|
+
item_id: itemId,
|
|
448
441
|
timestamp: Date.now(),
|
|
449
|
-
client_context:
|
|
442
|
+
client_context: clientContext,
|
|
450
443
|
};
|
|
451
444
|
|
|
452
445
|
const json = JSON.stringify(command);
|
|
453
|
-
const
|
|
446
|
+
const { compressDeflate } = shared_1;
|
|
447
|
+
const payload = await compressDeflate(json);
|
|
454
448
|
|
|
455
449
|
this.enhancedDebug(`Publishing mark as seen to MQTT`);
|
|
456
450
|
const result = await mqtt.publish({
|
|
457
451
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
458
|
-
qosLevel:
|
|
452
|
+
qosLevel: 1,
|
|
459
453
|
payload: payload,
|
|
460
454
|
});
|
|
461
455
|
|
|
462
456
|
this.enhancedDebug(`✅ Message marked as seen via MQTT!`);
|
|
463
457
|
return result;
|
|
464
458
|
} catch (err) {
|
|
465
|
-
this.enhancedDebug(`Mark as seen failed: ${err
|
|
459
|
+
this.enhancedDebug(`Mark as seen failed: ${err.message}`);
|
|
466
460
|
throw err;
|
|
467
461
|
}
|
|
468
462
|
}
|
|
@@ -479,35 +473,36 @@ class EnhancedDirectCommands {
|
|
|
479
473
|
throw new Error('MQTT client not available');
|
|
480
474
|
}
|
|
481
475
|
|
|
482
|
-
const ctx =
|
|
476
|
+
const ctx = clientContext || (0, uuid_1.v4)();
|
|
483
477
|
const command = {
|
|
484
478
|
action: 'indicate_activity',
|
|
485
|
-
thread_id:
|
|
486
|
-
is_active:
|
|
479
|
+
thread_id: threadId,
|
|
480
|
+
is_active: isActive,
|
|
487
481
|
timestamp: Date.now(),
|
|
488
482
|
client_context: ctx,
|
|
489
483
|
};
|
|
490
484
|
|
|
491
485
|
const json = JSON.stringify(command);
|
|
492
|
-
const
|
|
486
|
+
const { compressDeflate } = shared_1;
|
|
487
|
+
const payload = await compressDeflate(json);
|
|
493
488
|
|
|
494
489
|
this.enhancedDebug(`Publishing activity indicator to MQTT`);
|
|
495
490
|
const result = await mqtt.publish({
|
|
496
491
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
497
|
-
qosLevel:
|
|
492
|
+
qosLevel: 1,
|
|
498
493
|
payload: payload,
|
|
499
494
|
});
|
|
500
495
|
|
|
501
496
|
this.enhancedDebug(`✅ Activity indicator sent via MQTT!`);
|
|
502
497
|
return result;
|
|
503
498
|
} catch (err) {
|
|
504
|
-
this.enhancedDebug(`Activity indicator failed: ${err
|
|
499
|
+
this.enhancedDebug(`Activity indicator failed: ${err.message}`);
|
|
505
500
|
throw err;
|
|
506
501
|
}
|
|
507
502
|
}
|
|
508
503
|
|
|
509
504
|
/**
|
|
510
|
-
* Send media (image/video) via MQTT
|
|
505
|
+
* Send media (image/video) via MQTT
|
|
511
506
|
*/
|
|
512
507
|
async sendMedia({ text, mediaId, threadId, clientContext }) {
|
|
513
508
|
this.enhancedDebug(`Sending media ${mediaId} to ${threadId} via MQTT`);
|
|
@@ -518,31 +513,32 @@ class EnhancedDirectCommands {
|
|
|
518
513
|
throw new Error('MQTT client not available');
|
|
519
514
|
}
|
|
520
515
|
|
|
521
|
-
const ctx =
|
|
516
|
+
const ctx = clientContext || (0, uuid_1.v4)();
|
|
522
517
|
const command = {
|
|
523
518
|
action: 'send_item',
|
|
524
|
-
thread_id:
|
|
519
|
+
thread_id: threadId,
|
|
525
520
|
item_type: 'media',
|
|
526
|
-
media_id:
|
|
527
|
-
text:
|
|
521
|
+
media_id: mediaId,
|
|
522
|
+
text: text || '',
|
|
528
523
|
timestamp: Date.now(),
|
|
529
524
|
client_context: ctx,
|
|
530
525
|
};
|
|
531
526
|
|
|
532
527
|
const json = JSON.stringify(command);
|
|
533
|
-
const
|
|
528
|
+
const { compressDeflate } = shared_1;
|
|
529
|
+
const payload = await compressDeflate(json);
|
|
534
530
|
|
|
535
531
|
this.enhancedDebug(`Publishing media to MQTT`);
|
|
536
532
|
const result = await mqtt.publish({
|
|
537
533
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
538
|
-
qosLevel:
|
|
534
|
+
qosLevel: 1,
|
|
539
535
|
payload: payload,
|
|
540
536
|
});
|
|
541
537
|
|
|
542
538
|
this.enhancedDebug(`✅ Media sent via MQTT!`);
|
|
543
539
|
return result;
|
|
544
540
|
} catch (err) {
|
|
545
|
-
this.enhancedDebug(`Media send failed: ${err
|
|
541
|
+
this.enhancedDebug(`Media send failed: ${err.message}`);
|
|
546
542
|
throw err;
|
|
547
543
|
}
|
|
548
544
|
}
|
|
@@ -559,31 +555,32 @@ class EnhancedDirectCommands {
|
|
|
559
555
|
throw new Error('MQTT client not available');
|
|
560
556
|
}
|
|
561
557
|
|
|
562
|
-
const ctx =
|
|
558
|
+
const ctx = clientContext || (0, uuid_1.v4)();
|
|
563
559
|
const command = {
|
|
564
560
|
action: 'send_item',
|
|
565
|
-
thread_id:
|
|
561
|
+
thread_id: threadId,
|
|
566
562
|
item_type: 'location',
|
|
567
|
-
location_id:
|
|
568
|
-
text:
|
|
563
|
+
location_id: locationId,
|
|
564
|
+
text: text || '',
|
|
569
565
|
timestamp: Date.now(),
|
|
570
566
|
client_context: ctx,
|
|
571
567
|
};
|
|
572
568
|
|
|
573
569
|
const json = JSON.stringify(command);
|
|
574
|
-
const
|
|
570
|
+
const { compressDeflate } = shared_1;
|
|
571
|
+
const payload = await compressDeflate(json);
|
|
575
572
|
|
|
576
573
|
this.enhancedDebug(`Publishing location to MQTT`);
|
|
577
574
|
const result = await mqtt.publish({
|
|
578
575
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
579
|
-
qosLevel:
|
|
576
|
+
qosLevel: 1,
|
|
580
577
|
payload: payload,
|
|
581
578
|
});
|
|
582
579
|
|
|
583
580
|
this.enhancedDebug(`✅ Location sent via MQTT!`);
|
|
584
581
|
return result;
|
|
585
582
|
} catch (err) {
|
|
586
|
-
this.enhancedDebug(`Location send failed: ${err
|
|
583
|
+
this.enhancedDebug(`Location send failed: ${err.message}`);
|
|
587
584
|
throw err;
|
|
588
585
|
}
|
|
589
586
|
}
|
|
@@ -600,31 +597,32 @@ class EnhancedDirectCommands {
|
|
|
600
597
|
throw new Error('MQTT client not available');
|
|
601
598
|
}
|
|
602
599
|
|
|
603
|
-
const ctx =
|
|
600
|
+
const ctx = clientContext || (0, uuid_1.v4)();
|
|
604
601
|
const command = {
|
|
605
602
|
action: 'send_item',
|
|
606
|
-
thread_id:
|
|
603
|
+
thread_id: threadId,
|
|
607
604
|
item_type: 'profile',
|
|
608
|
-
user_id:
|
|
609
|
-
text:
|
|
605
|
+
user_id: userId,
|
|
606
|
+
text: text || '',
|
|
610
607
|
timestamp: Date.now(),
|
|
611
608
|
client_context: ctx,
|
|
612
609
|
};
|
|
613
610
|
|
|
614
611
|
const json = JSON.stringify(command);
|
|
615
|
-
const
|
|
612
|
+
const { compressDeflate } = shared_1;
|
|
613
|
+
const payload = await compressDeflate(json);
|
|
616
614
|
|
|
617
615
|
this.enhancedDebug(`Publishing profile to MQTT`);
|
|
618
616
|
const result = await mqtt.publish({
|
|
619
617
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
620
|
-
qosLevel:
|
|
618
|
+
qosLevel: 1,
|
|
621
619
|
payload: payload,
|
|
622
620
|
});
|
|
623
621
|
|
|
624
622
|
this.enhancedDebug(`✅ Profile sent via MQTT!`);
|
|
625
623
|
return result;
|
|
626
624
|
} catch (err) {
|
|
627
|
-
this.enhancedDebug(`Profile send failed: ${err
|
|
625
|
+
this.enhancedDebug(`Profile send failed: ${err.message}`);
|
|
628
626
|
throw err;
|
|
629
627
|
}
|
|
630
628
|
}
|
|
@@ -641,31 +639,32 @@ class EnhancedDirectCommands {
|
|
|
641
639
|
throw new Error('MQTT client not available');
|
|
642
640
|
}
|
|
643
641
|
|
|
644
|
-
const ctx =
|
|
642
|
+
const ctx = clientContext || (0, uuid_1.v4)();
|
|
645
643
|
const command = {
|
|
646
644
|
action: 'send_item',
|
|
647
|
-
thread_id:
|
|
645
|
+
thread_id: threadId,
|
|
648
646
|
item_type: 'hashtag',
|
|
649
|
-
hashtag:
|
|
650
|
-
text:
|
|
647
|
+
hashtag: hashtag,
|
|
648
|
+
text: text || '',
|
|
651
649
|
timestamp: Date.now(),
|
|
652
650
|
client_context: ctx,
|
|
653
651
|
};
|
|
654
652
|
|
|
655
653
|
const json = JSON.stringify(command);
|
|
656
|
-
const
|
|
654
|
+
const { compressDeflate } = shared_1;
|
|
655
|
+
const payload = await compressDeflate(json);
|
|
657
656
|
|
|
658
657
|
this.enhancedDebug(`Publishing hashtag to MQTT`);
|
|
659
658
|
const result = await mqtt.publish({
|
|
660
659
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
661
|
-
qosLevel:
|
|
660
|
+
qosLevel: 1,
|
|
662
661
|
payload: payload,
|
|
663
662
|
});
|
|
664
663
|
|
|
665
664
|
this.enhancedDebug(`✅ Hashtag sent via MQTT!`);
|
|
666
665
|
return result;
|
|
667
666
|
} catch (err) {
|
|
668
|
-
this.enhancedDebug(`Hashtag send failed: ${err
|
|
667
|
+
this.enhancedDebug(`Hashtag send failed: ${err.message}`);
|
|
669
668
|
throw err;
|
|
670
669
|
}
|
|
671
670
|
}
|
|
@@ -682,29 +681,30 @@ class EnhancedDirectCommands {
|
|
|
682
681
|
throw new Error('MQTT client not available');
|
|
683
682
|
}
|
|
684
683
|
|
|
685
|
-
const ctx =
|
|
684
|
+
const ctx = clientContext || (0, uuid_1.v4)();
|
|
686
685
|
const command = {
|
|
687
686
|
action: 'send_item',
|
|
688
|
-
thread_id:
|
|
687
|
+
thread_id: threadId,
|
|
689
688
|
item_type: 'like',
|
|
690
689
|
timestamp: Date.now(),
|
|
691
690
|
client_context: ctx,
|
|
692
691
|
};
|
|
693
692
|
|
|
694
693
|
const json = JSON.stringify(command);
|
|
695
|
-
const
|
|
694
|
+
const { compressDeflate } = shared_1;
|
|
695
|
+
const payload = await compressDeflate(json);
|
|
696
696
|
|
|
697
697
|
this.enhancedDebug(`Publishing like to MQTT`);
|
|
698
698
|
const result = await mqtt.publish({
|
|
699
699
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
700
|
-
qosLevel:
|
|
700
|
+
qosLevel: 1,
|
|
701
701
|
payload: payload,
|
|
702
702
|
});
|
|
703
703
|
|
|
704
704
|
this.enhancedDebug(`✅ Like sent via MQTT!`);
|
|
705
705
|
return result;
|
|
706
706
|
} catch (err) {
|
|
707
|
-
this.enhancedDebug(`Like send failed: ${err
|
|
707
|
+
this.enhancedDebug(`Like send failed: ${err.message}`);
|
|
708
708
|
throw err;
|
|
709
709
|
}
|
|
710
710
|
}
|
|
@@ -721,42 +721,52 @@ class EnhancedDirectCommands {
|
|
|
721
721
|
throw new Error('MQTT client not available');
|
|
722
722
|
}
|
|
723
723
|
|
|
724
|
-
const ctx =
|
|
724
|
+
const ctx = clientContext || (0, uuid_1.v4)();
|
|
725
725
|
const command = {
|
|
726
726
|
action: 'send_item',
|
|
727
|
-
thread_id:
|
|
727
|
+
thread_id: threadId,
|
|
728
728
|
item_type: 'story',
|
|
729
|
-
story_id:
|
|
730
|
-
text:
|
|
729
|
+
story_id: storyId,
|
|
730
|
+
text: text || '',
|
|
731
731
|
timestamp: Date.now(),
|
|
732
732
|
client_context: ctx,
|
|
733
733
|
};
|
|
734
734
|
|
|
735
735
|
const json = JSON.stringify(command);
|
|
736
|
-
const
|
|
736
|
+
const { compressDeflate } = shared_1;
|
|
737
|
+
const payload = await compressDeflate(json);
|
|
737
738
|
|
|
738
739
|
this.enhancedDebug(`Publishing story to MQTT`);
|
|
739
740
|
const result = await mqtt.publish({
|
|
740
741
|
topic: constants_1.Topics.SEND_MESSAGE.id,
|
|
741
|
-
qosLevel:
|
|
742
|
+
qosLevel: 1,
|
|
742
743
|
payload: payload,
|
|
743
744
|
});
|
|
744
745
|
|
|
745
746
|
this.enhancedDebug(`✅ Story sent via MQTT!`);
|
|
746
747
|
return result;
|
|
747
748
|
} catch (err) {
|
|
748
|
-
this.enhancedDebug(`Story send failed: ${err
|
|
749
|
+
this.enhancedDebug(`Story send failed: ${err.message}`);
|
|
749
750
|
throw err;
|
|
750
751
|
}
|
|
751
752
|
}
|
|
752
753
|
|
|
753
754
|
/**
|
|
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
|
|
755
764
|
*/
|
|
756
765
|
async sendPhotoViaRealtime({ photoBuffer, threadId, caption = '', mimeType = 'image/jpeg', clientContext }) {
|
|
757
766
|
this.enhancedDebug(`Sending photo to thread ${threadId} via Realtime`);
|
|
758
767
|
|
|
759
768
|
try {
|
|
769
|
+
// Validate inputs
|
|
760
770
|
if (!photoBuffer || !Buffer.isBuffer(photoBuffer) || photoBuffer.length === 0) {
|
|
761
771
|
throw new Error('photoBuffer must be a non-empty Buffer');
|
|
762
772
|
}
|
|
@@ -764,13 +774,17 @@ class EnhancedDirectCommands {
|
|
|
764
774
|
throw new Error('threadId is required');
|
|
765
775
|
}
|
|
766
776
|
|
|
777
|
+
// Get the ig client from realtime client
|
|
767
778
|
const ig = this.realtimeClient.ig;
|
|
768
779
|
if (!ig || !ig.request) {
|
|
769
780
|
throw new Error('Instagram client not available. Make sure you are logged in.');
|
|
770
781
|
}
|
|
771
782
|
|
|
783
|
+
// Step 1: Upload photo using rupload endpoint
|
|
784
|
+
this.enhancedDebug(`Step 1: Uploading photo (${photoBuffer.length} bytes)...`);
|
|
785
|
+
|
|
772
786
|
const uploadId = Date.now().toString();
|
|
773
|
-
const objectName = `${
|
|
787
|
+
const objectName = `${(0, uuid_1.v4)()}.${mimeType === 'image/png' ? 'png' : 'jpg'}`;
|
|
774
788
|
|
|
775
789
|
const isJpeg = mimeType === 'image/jpeg' || mimeType === 'image/jpg';
|
|
776
790
|
const compression = isJpeg
|
|
@@ -788,7 +802,7 @@ class EnhancedDirectCommands {
|
|
|
788
802
|
const uploadHeaders = {
|
|
789
803
|
'X-Instagram-Rupload-Params': JSON.stringify(ruploadParams),
|
|
790
804
|
'Content-Type': mimeType,
|
|
791
|
-
'X_FB_PHOTO_WATERFALL_ID':
|
|
805
|
+
'X_FB_PHOTO_WATERFALL_ID': (0, uuid_1.v4)(),
|
|
792
806
|
'X-Entity-Type': mimeType,
|
|
793
807
|
'X-Entity-Length': String(photoBuffer.length),
|
|
794
808
|
'Content-Length': String(photoBuffer.length),
|
|
@@ -810,11 +824,11 @@ class EnhancedDirectCommands {
|
|
|
810
824
|
}
|
|
811
825
|
this.enhancedDebug(`✅ Photo uploaded! upload_id: ${serverUploadId}`);
|
|
812
826
|
} catch (uploadErr) {
|
|
813
|
-
this.enhancedDebug(`Upload error: ${uploadErr
|
|
814
|
-
throw new Error(`Photo upload failed: ${uploadErr
|
|
827
|
+
this.enhancedDebug(`Upload error: ${uploadErr.message}`);
|
|
828
|
+
throw new Error(`Photo upload failed: ${uploadErr.message}`);
|
|
815
829
|
}
|
|
816
830
|
|
|
817
|
-
// Broadcast
|
|
831
|
+
// Step 2: Broadcast the uploaded photo to the thread
|
|
818
832
|
this.enhancedDebug(`Step 2: Broadcasting photo to thread ${threadId}...`);
|
|
819
833
|
|
|
820
834
|
const broadcastForm = {
|
|
@@ -837,12 +851,12 @@ class EnhancedDirectCommands {
|
|
|
837
851
|
this.enhancedDebug(`✅ Photo sent successfully to thread ${threadId}!`);
|
|
838
852
|
return broadcastResponse;
|
|
839
853
|
} catch (broadcastErr) {
|
|
840
|
-
this.enhancedDebug(`Broadcast error: ${broadcastErr
|
|
841
|
-
throw new Error(`Photo broadcast failed: ${broadcastErr
|
|
854
|
+
this.enhancedDebug(`Broadcast error: ${broadcastErr.message}`);
|
|
855
|
+
throw new Error(`Photo broadcast failed: ${broadcastErr.message}`);
|
|
842
856
|
}
|
|
843
857
|
|
|
844
858
|
} catch (err) {
|
|
845
|
-
this.enhancedDebug(`sendPhotoViaRealtime failed: ${err
|
|
859
|
+
this.enhancedDebug(`sendPhotoViaRealtime failed: ${err.message}`);
|
|
846
860
|
throw err;
|
|
847
861
|
}
|
|
848
862
|
}
|
|
@@ -856,11 +870,21 @@ class EnhancedDirectCommands {
|
|
|
856
870
|
|
|
857
871
|
/**
|
|
858
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
|
|
859
882
|
*/
|
|
860
883
|
async sendVideoViaRealtime({ videoBuffer, threadId, caption = '', duration = 0, width = 720, height = 1280, clientContext }) {
|
|
861
884
|
this.enhancedDebug(`Sending video to thread ${threadId} via Realtime`);
|
|
862
885
|
|
|
863
886
|
try {
|
|
887
|
+
// Validate inputs
|
|
864
888
|
if (!videoBuffer || !Buffer.isBuffer(videoBuffer) || videoBuffer.length === 0) {
|
|
865
889
|
throw new Error('videoBuffer must be a non-empty Buffer');
|
|
866
890
|
}
|
|
@@ -868,17 +892,21 @@ class EnhancedDirectCommands {
|
|
|
868
892
|
throw new Error('threadId is required');
|
|
869
893
|
}
|
|
870
894
|
|
|
895
|
+
// Get the ig client from realtime client
|
|
871
896
|
const ig = this.realtimeClient.ig;
|
|
872
897
|
if (!ig || !ig.request) {
|
|
873
898
|
throw new Error('Instagram client not available. Make sure you are logged in.');
|
|
874
899
|
}
|
|
875
900
|
|
|
901
|
+
// Step 1: Upload video using rupload endpoint
|
|
902
|
+
this.enhancedDebug(`Step 1: Uploading video (${videoBuffer.length} bytes)...`);
|
|
903
|
+
|
|
876
904
|
const uploadId = Date.now().toString();
|
|
877
|
-
const objectName = `${
|
|
905
|
+
const objectName = `${(0, uuid_1.v4)()}.mp4`;
|
|
878
906
|
|
|
879
907
|
const ruploadParams = {
|
|
880
908
|
upload_id: uploadId,
|
|
881
|
-
media_type: 2,
|
|
909
|
+
media_type: 2, // 2 = video
|
|
882
910
|
xsharing_user_ids: JSON.stringify([]),
|
|
883
911
|
upload_media_duration_ms: Math.round(duration * 1000),
|
|
884
912
|
upload_media_width: width,
|
|
@@ -888,7 +916,7 @@ class EnhancedDirectCommands {
|
|
|
888
916
|
const uploadHeaders = {
|
|
889
917
|
'X-Instagram-Rupload-Params': JSON.stringify(ruploadParams),
|
|
890
918
|
'Content-Type': 'video/mp4',
|
|
891
|
-
'X_FB_VIDEO_WATERFALL_ID':
|
|
919
|
+
'X_FB_VIDEO_WATERFALL_ID': (0, uuid_1.v4)(),
|
|
892
920
|
'X-Entity-Type': 'video/mp4',
|
|
893
921
|
'X-Entity-Length': String(videoBuffer.length),
|
|
894
922
|
'Content-Length': String(videoBuffer.length),
|
|
@@ -911,11 +939,11 @@ class EnhancedDirectCommands {
|
|
|
911
939
|
}
|
|
912
940
|
this.enhancedDebug(`✅ Video uploaded! upload_id: ${serverUploadId}`);
|
|
913
941
|
} catch (uploadErr) {
|
|
914
|
-
this.enhancedDebug(`Video upload error: ${uploadErr
|
|
915
|
-
throw new Error(`Video upload failed: ${uploadErr
|
|
942
|
+
this.enhancedDebug(`Video upload error: ${uploadErr.message}`);
|
|
943
|
+
throw new Error(`Video upload failed: ${uploadErr.message}`);
|
|
916
944
|
}
|
|
917
945
|
|
|
918
|
-
// Broadcast the uploaded video
|
|
946
|
+
// Step 2: Broadcast the uploaded video to the thread
|
|
919
947
|
this.enhancedDebug(`Step 2: Broadcasting video to thread ${threadId}...`);
|
|
920
948
|
|
|
921
949
|
const broadcastForm = {
|
|
@@ -939,12 +967,12 @@ class EnhancedDirectCommands {
|
|
|
939
967
|
this.enhancedDebug(`✅ Video sent successfully to thread ${threadId}!`);
|
|
940
968
|
return broadcastResponse;
|
|
941
969
|
} catch (broadcastErr) {
|
|
942
|
-
this.enhancedDebug(`Video broadcast error: ${broadcastErr
|
|
943
|
-
throw new Error(`Video broadcast failed: ${broadcastErr
|
|
970
|
+
this.enhancedDebug(`Video broadcast error: ${broadcastErr.message}`);
|
|
971
|
+
throw new Error(`Video broadcast failed: ${broadcastErr.message}`);
|
|
944
972
|
}
|
|
945
973
|
|
|
946
974
|
} catch (err) {
|
|
947
|
-
this.enhancedDebug(`sendVideoViaRealtime failed: ${err
|
|
975
|
+
this.enhancedDebug(`sendVideoViaRealtime failed: ${err.message}`);
|
|
948
976
|
throw err;
|
|
949
977
|
}
|
|
950
978
|
}
|
|
@@ -1,24 +1,30 @@
|
|
|
1
|
-
// realtime.client.js
|
|
2
1
|
'use strict';
|
|
3
2
|
|
|
4
3
|
/*
|
|
5
4
|
RealtimeClient
|
|
6
5
|
--------------
|
|
7
6
|
This file implements the RealtimeClient which manages:
|
|
8
|
-
- constructing the FBNS/MQTT connection payload
|
|
7
|
+
- constructing the FBNS/MQTT connection payload (Thrift)
|
|
9
8
|
- starting the MQTT client (MQTToTClient)
|
|
10
9
|
- attaching lifecycle handlers (connect/close/error)
|
|
11
10
|
- keepalives, message-sync refresh and traffic watchdogs
|
|
12
11
|
- wiring MQTT messages into higher-level events (message, iris, receive)
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
The implementation keeps original structure while applying compatibility tweaks:
|
|
14
|
+
- persistent clientMqttSessionId and client_context handling
|
|
15
|
+
- robust sessionid / mqttJwt / deviceSecret fallbacks
|
|
16
|
+
- slightly adjusted appSpecificInfo to match mobile client fields
|
|
17
|
+
- uses mqttot.MQTToTConnection to build a thrift connection payload
|
|
18
|
+
- MQTT URL remains 'edge-mqtt.facebook.com' (Instagram/Meta edge host)
|
|
19
|
+
Comments are in English next to logic so you can follow what's happening.
|
|
14
20
|
*/
|
|
15
21
|
|
|
16
|
-
//
|
|
22
|
+
// Keep module imports similar to your original code
|
|
17
23
|
const constants_1 = require("../constants");
|
|
18
24
|
const commands_1 = require("./commands");
|
|
19
25
|
const shared_1 = require("../shared");
|
|
20
26
|
const mqttot_1 = require("../mqttot");
|
|
21
|
-
//
|
|
27
|
+
// Use mqtts for errors / IllegalStateError compatibility
|
|
22
28
|
const mqtts_1 = require("mqtts");
|
|
23
29
|
const errors_1 = require("../errors");
|
|
24
30
|
const eventemitter3_1 = require("eventemitter3");
|
|
@@ -32,7 +38,7 @@ const gap_handler_1 = require("./features/gap-handler");
|
|
|
32
38
|
const enhanced_direct_commands_1 = require("./commands/enhanced.direct.commands");
|
|
33
39
|
const presence_typing_mixin_1 = require("./mixins/presence-typing.mixin");
|
|
34
40
|
|
|
35
|
-
// Use INSTAGRAM_VERSION exported from mqttot so it is applied automatically
|
|
41
|
+
// Use INSTAGRAM_VERSION exported from mqttot so it is applied automatically where available
|
|
36
42
|
const INSTAGRAM_VERSION = mqttot_1.INSTAGRAM_VERSION;
|
|
37
43
|
|
|
38
44
|
/**
|
|
@@ -57,6 +63,9 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
57
63
|
this.realtimeDebug = (0, shared_1.debugChannel)('realtime');
|
|
58
64
|
this.messageDebug = this.realtimeDebug.extend('message');
|
|
59
65
|
|
|
66
|
+
// enhanced direct commands debug (exposed for compatibility with the enhanced commands)
|
|
67
|
+
this.enhancedDebug = this.realtimeDebug.extend('enhanced-commands');
|
|
68
|
+
|
|
60
69
|
// safeDisconnect flag used when user intentionally disconnects
|
|
61
70
|
this.safeDisconnect = false;
|
|
62
71
|
|
|
@@ -81,6 +90,10 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
81
90
|
// apply mixins to this instance (keeps modular features separated)
|
|
82
91
|
(0, mixins_1.applyMixins)(mixins, this, this.ig);
|
|
83
92
|
|
|
93
|
+
// Default subscriptions (force-enable if saved ones are empty)
|
|
94
|
+
this.defaultGraphQlSubs = ['ig_sub_direct', 'ig_sub_direct_v2_message_sync'];
|
|
95
|
+
this.defaultSkywalkerSubs = ['presence_subscribe', 'typing_subscribe'];
|
|
96
|
+
|
|
84
97
|
// internal flags & timers
|
|
85
98
|
this._attachedAuthState = null;
|
|
86
99
|
this._messageSyncAttached = false;
|
|
@@ -314,6 +327,7 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
314
327
|
* - Pulls deviceId, sessionid, device secrets and app-specific headers to populate the payload.
|
|
315
328
|
*/
|
|
316
329
|
constructConnection() {
|
|
330
|
+
// Choose the best available user agent value from state fallbacks
|
|
317
331
|
const userAgent =
|
|
318
332
|
typeof this.ig.state.userAgent === 'string'
|
|
319
333
|
? this.ig.state.userAgent
|
|
@@ -323,8 +337,10 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
323
337
|
? this.ig.state.deviceString
|
|
324
338
|
: 'Instagram 155.0.0.37.107 Android';
|
|
325
339
|
|
|
340
|
+
// deviceId / phoneId fallback handling (string coercion)
|
|
326
341
|
const deviceId = String(this.ig.state.phoneId || this.ig.state.deviceId || 'device_unknown');
|
|
327
342
|
|
|
343
|
+
// attempt to extract sessionid from various locations: Authorization JWT, cookie helpers, state fields, or cookie jar
|
|
328
344
|
let sessionid = null;
|
|
329
345
|
try {
|
|
330
346
|
sessionid = this.extractSessionIdFromJWT();
|
|
@@ -354,12 +370,14 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
354
370
|
} catch (e) {}
|
|
355
371
|
}
|
|
356
372
|
|
|
373
|
+
// fallback sessionid generation — only used if nothing else found
|
|
357
374
|
if (!sessionid) {
|
|
358
375
|
const userId = this.ig.state.cookieUserId || this.ig.state.userId || '0';
|
|
359
376
|
sessionid = String(userId) + '_' + Date.now();
|
|
360
377
|
this.realtimeDebug(`SessionID generated (fallback): ${sessionid}`);
|
|
361
378
|
}
|
|
362
379
|
|
|
380
|
+
// device secret retrieval (from attached auth helper or state)
|
|
363
381
|
let deviceSecret = null;
|
|
364
382
|
try {
|
|
365
383
|
if (this._attachedAuthState && typeof this._attachedAuthState.getData === 'function') {
|
|
@@ -388,6 +406,7 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
388
406
|
if (!mqttJwt && this.ig.state.mqttJwt) mqttJwt = this.ig.state.mqttJwt;
|
|
389
407
|
} catch (e) {}
|
|
390
408
|
|
|
409
|
+
// password is either "jwt=..." or "sessionid=..."
|
|
391
410
|
let password;
|
|
392
411
|
if (mqttJwt) {
|
|
393
412
|
password = `jwt=${mqttJwt}`;
|
|
@@ -395,9 +414,10 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
395
414
|
password = `sessionid=${sessionid}`;
|
|
396
415
|
}
|
|
397
416
|
|
|
417
|
+
// client type indicates if device secret is available
|
|
398
418
|
const clientType = deviceSecret ? 'secure_cookie_auth' : 'cookie_auth';
|
|
399
419
|
|
|
400
|
-
// IMPORTANT: keep clientMqttSessionId persistent across reconnects
|
|
420
|
+
// IMPORTANT: keep clientMqttSessionId persistent across reconnects (already set in constructor)
|
|
401
421
|
if (!this._clientMqttSessionId) {
|
|
402
422
|
try {
|
|
403
423
|
this._clientMqttSessionId = (BigInt(Date.now()) & BigInt(0xffffffff));
|
|
@@ -405,19 +425,21 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
405
425
|
this._clientMqttSessionId = BigInt(0);
|
|
406
426
|
}
|
|
407
427
|
}
|
|
408
|
-
|
|
409
428
|
const clientMqttSessionId = this._clientMqttSessionId;
|
|
410
429
|
|
|
430
|
+
// numeric topics Instagram uses for subscription mapping (kept consistent)
|
|
411
431
|
const subscribeTopics = [88, 135, 149, 150, 133, 146];
|
|
412
432
|
|
|
413
433
|
// Build the thrift connection object using mqttot.MQTToTConnection
|
|
434
|
+
// NOTE: use deviceId.substring(0,20) for clientIdentifier because the mobile app often truncates it.
|
|
435
|
+
// endpointCapabilities set to 128 for broader compatibility (some clients use 0, 128 provides better capability advertising).
|
|
414
436
|
this.connection = new mqttot_1.MQTToTConnection({
|
|
415
437
|
clientIdentifier: deviceId.substring(0, 20),
|
|
416
438
|
clientInfo: {
|
|
417
439
|
userId: BigInt(Number(this.ig.state.cookieUserId || this.ig.state.userId || 0)),
|
|
418
440
|
userAgent,
|
|
419
441
|
clientCapabilities: 183,
|
|
420
|
-
endpointCapabilities:
|
|
442
|
+
endpointCapabilities: 128,
|
|
421
443
|
publishFormat: 1,
|
|
422
444
|
noAutomaticForeground: false,
|
|
423
445
|
makeUserAvailableInForeground: true,
|
|
@@ -444,8 +466,13 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
444
466
|
video_call_participant_state_delivery: '17977239895057311',
|
|
445
467
|
presence_subscribe: '17846944882223835',
|
|
446
468
|
}),
|
|
469
|
+
// Extra app-specific fields observed in the mobile APK (helps the server identify the client capabilities)
|
|
447
470
|
'User-Agent': userAgent,
|
|
448
471
|
'Accept-Language': (this.ig.state.language || 'en_US').replace('_', '-'),
|
|
472
|
+
platform: 'android',
|
|
473
|
+
ig_mqtt_route: 'django',
|
|
474
|
+
pubsub_msg_type_blacklist: 'direct, typing_type',
|
|
475
|
+
auth_cache_enabled: '0',
|
|
449
476
|
},
|
|
450
477
|
});
|
|
451
478
|
}
|
|
@@ -557,7 +584,7 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
557
584
|
this._syncTimer = setInterval(async () => {
|
|
558
585
|
try {
|
|
559
586
|
if (!this.commands) return;
|
|
560
|
-
const subs = (this.initOptions && this.initOptions.graphQlSubs && this.initOptions.graphQlSubs.length) ? this.initOptions.graphQlSubs :
|
|
587
|
+
const subs = (this.initOptions && this.initOptions.graphQlSubs && this.initOptions.graphQlSubs.length) ? this.initOptions.graphQlSubs : this.defaultGraphQlSubs;
|
|
561
588
|
await this.graphQlSubscribe(subs);
|
|
562
589
|
this.realtimeDebug('[WATCHDOG] MESSAGE_SYNC refreshed.');
|
|
563
590
|
} catch (e) {
|
|
@@ -620,6 +647,9 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
620
647
|
await (0, shared_1.delay)(100);
|
|
621
648
|
if (this.initOptions.graphQlSubs && this.initOptions.graphQlSubs.length > 0) {
|
|
622
649
|
await this.graphQlSubscribe(this.initOptions.graphQlSubs);
|
|
650
|
+
} else {
|
|
651
|
+
// ensure defaults if none provided
|
|
652
|
+
await this.graphQlSubscribe(this.defaultGraphQlSubs);
|
|
623
653
|
}
|
|
624
654
|
if (this.initOptions.irisData) {
|
|
625
655
|
await this.irisSubscribe(this.initOptions.irisData);
|
|
@@ -637,6 +667,9 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
637
667
|
}
|
|
638
668
|
if ((this.initOptions.skywalkerSubs ?? []).length > 0) {
|
|
639
669
|
await this.skywalkerSubscribe(this.initOptions.skywalkerSubs);
|
|
670
|
+
} else {
|
|
671
|
+
// ensure default skywalker subs if none provided
|
|
672
|
+
await this.skywalkerSubscribe(this.defaultSkywalkerSubs);
|
|
640
673
|
}
|
|
641
674
|
await (0, shared_1.delay)(100);
|
|
642
675
|
try {
|
|
@@ -790,8 +823,8 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
790
823
|
}
|
|
791
824
|
|
|
792
825
|
const connectOptions = {
|
|
793
|
-
graphQlSubs: options.graphQlSubs || savedOptions.graphQlSubs ||
|
|
794
|
-
skywalkerSubs: options.skywalkerSubs || savedOptions.skywalkerSubs ||
|
|
826
|
+
graphQlSubs: options.graphQlSubs || savedOptions.graphQlSubs || this.defaultGraphQlSubs,
|
|
827
|
+
skywalkerSubs: options.skywalkerSubs || savedOptions.skywalkerSubs || this.defaultSkywalkerSubs,
|
|
795
828
|
irisData,
|
|
796
829
|
...options
|
|
797
830
|
};
|
|
@@ -872,6 +905,8 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
872
905
|
if (!this.commands) {
|
|
873
906
|
throw new mqtts_1.IllegalStateError('connect() must be called before graphQlSubscribe()');
|
|
874
907
|
}
|
|
908
|
+
// If the caller provided an empty array, ensure defaults are used
|
|
909
|
+
if (Array.isArray(sub) && sub.length === 0) sub = this.defaultGraphQlSubs;
|
|
875
910
|
this.realtimeDebug(`Subscribing with GraphQL to ${sub.join(', ')}`);
|
|
876
911
|
return this.commands.updateSubscriptions({
|
|
877
912
|
topic: constants_1.Topics.REALTIME_SUB,
|
|
@@ -890,6 +925,8 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
890
925
|
if (!this.commands) {
|
|
891
926
|
throw new mqtts_1.IllegalStateError('connect() must be called before skywalkerSubscribe()');
|
|
892
927
|
}
|
|
928
|
+
// If empty, use defaults
|
|
929
|
+
if (Array.isArray(sub) && sub.length === 0) sub = this.defaultSkywalkerSubs;
|
|
893
930
|
this.realtimeDebug(`Subscribing with Skywalker to ${sub.join(', ')}`);
|
|
894
931
|
return this.commands.updateSubscriptions({
|
|
895
932
|
topic: constants_1.Topics.PUBSUB,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodejs-insta-private-api-mqtt",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.30",
|
|
4
4
|
"description": "Complete Instagram MQTT protocol with FULL iOS + Android support. 33 device presets (21 iOS + 12 Android). iPhone 16/15/14/13/12, iPad Pro, Samsung, Pixel, Huawei. Real-time DM messaging, view-once media extraction, sub-500ms latency.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|