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 { v4: uuidv4 } = require("uuid");
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, clientContext) {
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 ctx = this._getClientContext(clientContext);
30
+ const clientContext = (0, uuid_1.v4)();
48
31
  const command = {
49
32
  action: 'send_item',
50
- thread_id: String(threadId),
33
+ thread_id: threadId,
51
34
  item_type: 'text',
52
- text: String(text || ''),
35
+ text: text,
53
36
  timestamp: Date.now(),
54
- client_context: ctx,
37
+ client_context: clientContext,
55
38
  };
56
39
 
57
40
  // Compress JSON payload
58
41
  const json = JSON.stringify(command);
59
- const payload = await shared_1.compressDeflate(json);
42
+ const { compressDeflate } = shared_1;
43
+ const payload = await compressDeflate(json);
60
44
 
61
- // Send to MQTT (QoS 0 for stability)
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: 0,
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?.message || 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, clientContext) {
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 ctx = this._getClientContext(clientContext);
73
+ const clientContext = (0, uuid_1.v4)();
90
74
  const command = {
91
75
  action: 'delete_item',
92
- thread_id: String(threadId),
93
- item_id: String(itemId),
76
+ thread_id: threadId,
77
+ item_id: itemId,
94
78
  timestamp: Date.now(),
95
- client_context: ctx,
79
+ client_context: clientContext,
96
80
  };
97
81
 
98
82
  const json = JSON.stringify(command);
99
- const payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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, clientContext) {
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 ctx = this._getClientContext(clientContext);
113
+ const clientContext = (0, uuid_1.v4)();
129
114
  const command = {
130
115
  action: 'edit_item',
131
- thread_id: String(threadId),
132
- item_id: String(itemId),
133
- text: String(newText || ''),
116
+ thread_id: threadId,
117
+ item_id: itemId,
118
+ text: newText,
134
119
  timestamp: Date.now(),
135
- client_context: ctx,
120
+ client_context: clientContext,
136
121
  };
137
122
 
138
123
  const json = JSON.stringify(command);
139
- const payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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, clientContext) {
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 ctx = this._getClientContext(clientContext);
154
+ const clientContext = (0, uuid_1.v4)();
169
155
  const command = {
170
156
  action: 'send_item',
171
- thread_id: String(threadId),
157
+ thread_id: threadId,
172
158
  item_type: 'text',
173
- text: String(replyText || ''),
174
- replying_to_item_id: String(messageId),
159
+ text: replyText,
160
+ replying_to_item_id: messageId,
175
161
  timestamp: Date.now(),
176
- client_context: ctx,
162
+ client_context: clientContext,
177
163
  };
178
164
 
179
165
  const json = JSON.stringify(command);
180
- const payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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(clientContext) {
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 ctx = this._getClientContext(clientContext);
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: ctx,
201
+ client_context: clientContext,
215
202
  };
216
203
 
217
204
  const json = JSON.stringify(command);
218
- const payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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(clientContext) {
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 ctx = this._getClientContext(clientContext);
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: ctx,
240
+ client_context: clientContext,
253
241
  };
254
242
 
255
243
  const json = JSON.stringify(command);
256
- const payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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(clientContext) {
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 ctx = this._getClientContext(clientContext);
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: ctx,
279
+ client_context: clientContext,
291
280
  };
292
281
 
293
282
  const json = JSON.stringify(command);
294
- const payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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, clientContext) {
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 ctx = this._getClientContext(clientContext);
313
+ const clientContext = (0, uuid_1.v4)();
324
314
  const command = {
325
315
  action: 'add_member',
326
- thread_id: String(threadId),
327
- user_id: String(userId),
316
+ thread_id: threadId,
317
+ user_id: userId,
328
318
  timestamp: Date.now(),
329
- client_context: ctx,
319
+ client_context: clientContext,
330
320
  };
331
321
 
332
322
  const json = JSON.stringify(command);
333
- const payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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, clientContext) {
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 ctx = this._getClientContext(clientContext);
353
+ const clientContext = (0, uuid_1.v4)();
363
354
  const command = {
364
355
  action: 'remove_member',
365
- thread_id: String(threadId),
366
- user_id: String(userId),
356
+ thread_id: threadId,
357
+ user_id: userId,
367
358
  timestamp: Date.now(),
368
- client_context: ctx,
359
+ client_context: clientContext,
369
360
  };
370
361
 
371
362
  const json = JSON.stringify(command);
372
- const payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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 = this._getClientContext(clientContext);
393
+ const ctx = clientContext || (0, uuid_1.v4)();
402
394
  const command = {
403
395
  action: 'send_reaction',
404
- thread_id: String(threadId),
405
- item_id: String(itemId),
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 payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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, clientContext }) {
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 ctx = this._getClientContext(clientContext);
436
+ const clientContext = (0, uuid_1.v4)();
444
437
  const command = {
445
438
  action: 'mark_as_seen',
446
- thread_id: String(threadId),
447
- item_id: String(itemId),
439
+ thread_id: threadId,
440
+ item_id: itemId,
448
441
  timestamp: Date.now(),
449
- client_context: ctx,
442
+ client_context: clientContext,
450
443
  };
451
444
 
452
445
  const json = JSON.stringify(command);
453
- const payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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 = this._getClientContext(clientContext);
476
+ const ctx = clientContext || (0, uuid_1.v4)();
483
477
  const command = {
484
478
  action: 'indicate_activity',
485
- thread_id: String(threadId),
486
- is_active: !!isActive,
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 payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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 (media id)
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 = this._getClientContext(clientContext);
516
+ const ctx = clientContext || (0, uuid_1.v4)();
522
517
  const command = {
523
518
  action: 'send_item',
524
- thread_id: String(threadId),
519
+ thread_id: threadId,
525
520
  item_type: 'media',
526
- media_id: String(mediaId),
527
- text: String(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 payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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 = this._getClientContext(clientContext);
558
+ const ctx = clientContext || (0, uuid_1.v4)();
563
559
  const command = {
564
560
  action: 'send_item',
565
- thread_id: String(threadId),
561
+ thread_id: threadId,
566
562
  item_type: 'location',
567
- location_id: String(locationId),
568
- text: String(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 payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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 = this._getClientContext(clientContext);
600
+ const ctx = clientContext || (0, uuid_1.v4)();
604
601
  const command = {
605
602
  action: 'send_item',
606
- thread_id: String(threadId),
603
+ thread_id: threadId,
607
604
  item_type: 'profile',
608
- user_id: String(userId),
609
- text: String(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 payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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 = this._getClientContext(clientContext);
642
+ const ctx = clientContext || (0, uuid_1.v4)();
645
643
  const command = {
646
644
  action: 'send_item',
647
- thread_id: String(threadId),
645
+ thread_id: threadId,
648
646
  item_type: 'hashtag',
649
- hashtag: String(hashtag),
650
- text: String(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 payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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 = this._getClientContext(clientContext);
684
+ const ctx = clientContext || (0, uuid_1.v4)();
686
685
  const command = {
687
686
  action: 'send_item',
688
- thread_id: String(threadId),
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 payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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 = this._getClientContext(clientContext);
724
+ const ctx = clientContext || (0, uuid_1.v4)();
725
725
  const command = {
726
726
  action: 'send_item',
727
- thread_id: String(threadId),
727
+ thread_id: threadId,
728
728
  item_type: 'story',
729
- story_id: String(storyId),
730
- text: String(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 payload = await shared_1.compressDeflate(json);
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: 0,
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?.message || 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 = `${uuidv4()}.${mimeType === 'image/png' ? 'png' : 'jpg'}`;
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': uuidv4(),
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?.message || uploadErr}`);
814
- throw new Error(`Photo upload failed: ${uploadErr?.message || 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?.message || broadcastErr}`);
841
- throw new Error(`Photo broadcast failed: ${broadcastErr?.message || 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?.message || 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 = `${uuidv4()}.mp4`;
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': uuidv4(),
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?.message || uploadErr}`);
915
- throw new Error(`Video upload failed: ${uploadErr?.message || 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?.message || broadcastErr}`);
943
- throw new Error(`Video broadcast failed: ${broadcastErr?.message || 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?.message || 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
- Comments below are English explanations added next to the existing logic.
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
- // (keep module imports headers the same as in your original code)
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
- // IMPORT MQTTS instead of the local shim (we're using mqtts package)
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: 0,
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 : ['ig_sub_direct', 'ig_sub_direct_v2_message_sync'];
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 || ['ig_sub_direct', 'ig_sub_direct_v2_message_sync'],
794
- skywalkerSubs: options.skywalkerSubs || savedOptions.skywalkerSubs || ['presence_subscribe', 'typing_subscribe'],
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.28",
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": {