nodejs-insta-private-api-mqtt 1.3.45 → 1.3.47

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.
@@ -1,5 +1,5 @@
1
- const APP_VERSION = '409.0.0.48.170';
2
- const APP_VERSION_CODE = '380706635';
1
+ const APP_VERSION = '420.0.0.42.95';
2
+ const APP_VERSION_CODE = '386614891';
3
3
  const INSTALL_LOCATION = '0';
4
4
  const COMPILED_SDK_VERSION = '36';
5
5
  const SIGNATURE_KEY = '9193488027538fd3450b83b7d05286d4ca9599a0f7eeed90d8c85925698a05dc';
@@ -35,9 +35,9 @@ class State {
35
35
 
36
36
  // ===== PLATFORM SUPPORT (iOS + Android) =====
37
37
  this.platform = 'android'; // 'android' or 'ios'
38
- this.iosVersion = '18.1';
39
- this.iosAppVersion = '347.0.0.36.89';
40
- this.iosAppVersionCode = '618023787';
38
+ this.iosVersion = '18.3';
39
+ this.iosAppVersion = '366.0.0.38.99';
40
+ this.iosAppVersionCode = '632412089';
41
41
  this.iosDeviceModel = 'iPhone16,2'; // iPhone 15 Pro Max
42
42
  this.iosDeviceName = 'iPhone';
43
43
  this.iosBundleId = 'com.burbn.instagram';
@@ -830,9 +830,9 @@ class State {
830
830
  const {
831
831
  iosDeviceModel = 'iPhone16,2',
832
832
  iosDeviceName = 'iPhone 15 Pro Max',
833
- iosVersion = '18.1',
834
- iosAppVersion = '347.0.0.36.89',
835
- iosAppVersionCode = '618023787'
833
+ iosVersion = '18.3',
834
+ iosAppVersion = '366.0.0.38.99',
835
+ iosAppVersionCode = '632412089'
836
836
  } = iosConfig || {};
837
837
 
838
838
  this.platform = 'ios';
@@ -356,7 +356,7 @@ class Utils {
356
356
 
357
357
  static buildHeaders({ userAgent, csrfToken, referer, extra = {} } = {}) {
358
358
  const base = {
359
- 'User-Agent': userAgent || this.formatUserAgent('401.0.0.48.79', 'Pixel', 'en_US', '40104879'),
359
+ 'User-Agent': userAgent || this.formatUserAgent('420.0.0.42.95', 'Pixel 8 Pro', 'en_US', '386614891'),
360
360
  'Accept': 'application/json, text/javascript, */*; q=0.01',
361
361
  'Accept-Language': 'en-US,en;q=0.9',
362
362
  'X-Requested-With': 'XMLHttpRequest',
@@ -371,16 +371,16 @@ class Utils {
371
371
  User agent builders
372
372
  ------------------------- */
373
373
 
374
- static formatUserAgent(appVersion = '401.0.0.48.79', deviceString = 'Pixel 5', language = 'en_US', appVersionCode = '40104879') {
374
+ static formatUserAgent(appVersion = '420.0.0.42.95', deviceString = 'Pixel 8 Pro', language = 'en_US', appVersionCode = '386614891') {
375
375
  return `Instagram ${appVersion} Android (${deviceString}; ${language}; ${appVersionCode})`;
376
376
  }
377
377
 
378
- static formatWebUserAgent(devicePayload = {}, build = 'OPM1', appUserAgent = '') {
379
- return `Mozilla/5.0 (Linux; Android ${devicePayload.android_release || '11'}; ${devicePayload.model || 'Pixel'}) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36 ${appUserAgent}`;
378
+ static formatWebUserAgent(devicePayload = {}, build = 'AP2A.240805.005', appUserAgent = '') {
379
+ return `Mozilla/5.0 (Linux; Android ${devicePayload.android_release || '14'}; ${devicePayload.model || 'Pixel 8 Pro'}) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.139 Mobile Safari/537.36 ${appUserAgent}`;
380
380
  }
381
381
 
382
382
  static createUserAgentFromDevice(device = {}) {
383
- return `Instagram ${device.appVersion || '401.0.0.48.79'} Android (${device.android_version || device.android_release || '11'}/${device.android_release || '11'}; ${device.dpi || ''}dpi; ${device.resolution || '1080x1920'}; ${device.manufacturer || 'Google'}; ${device.model || 'Pixel'}; ${device.device || 'walleye'}; ${device.cpu || 'arm64-v8a'})`;
383
+ return `Instagram ${device.appVersion || '420.0.0.42.95'} Android (${device.android_version || device.android_release || '14'}/${device.android_release || '14'}; ${device.dpi || '480'}dpi; ${device.resolution || '1344x2992'}; ${device.manufacturer || 'Google'}; ${device.model || 'Pixel 8 Pro'}; ${device.device || 'husky'}; ${device.cpu || 'arm64-v8a'})`;
384
384
  }
385
385
 
386
386
  /* -------------------------
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.mqttotConnectFlow = exports.MQTToTClient = void 0;
5
5
  // Export the Instagram version so it can be used programmatically
6
- exports.INSTAGRAM_VERSION = '414.0.0.40.83';
6
+ exports.INSTAGRAM_VERSION = '420.0.0.42.95';
7
7
  const shared_1 = require("../shared");
8
8
  const mqttot_connect_request_packet_1 = require("./mqttot.connect.request.packet");
9
9
  // *** Change: import the external mqtts package instead of a local mqtt-shim ***
@@ -132,7 +132,7 @@ function mqttotConnectFlow(payload, requirePayload) {
132
132
  type: mqtts_1.PacketType.Connect,
133
133
  options: {
134
134
  payload,
135
- keepAlive: 60,
135
+ keepAlive: 20,
136
136
  },
137
137
  }),
138
138
  accept: mqtts_1.isConnAck,
@@ -118,6 +118,9 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
118
118
  this._mqttSessionId = null; // actual server-provided mqtt session id (string)
119
119
  this._mqttSessionPersistIntervalId = null; // periodic persist interval handler
120
120
 
121
+ // Active keepalive/query timer (added)
122
+ this._activeKeepaliveTimer = null;
123
+
121
124
  // Persisted identity items that must survive reconnects:
122
125
  // - clientMqttSessionId must NOT be re-generated each connect
123
126
  // - _clientContext for EnhancedDirectCommands (for message identity)
@@ -388,7 +391,7 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
388
391
  ? this.ig.state.appUserAgent
389
392
  : typeof this.ig.state.deviceString === 'string'
390
393
  ? this.ig.state.deviceString
391
- : 'Instagram 155.0.0.37.107 Android';
394
+ : 'Instagram 420.0.0.42.95 Android';
392
395
 
393
396
  // deviceId / phoneId fallback handling (string coercion)
394
397
  const deviceId = String(this.ig.state.phoneId || this.ig.state.deviceId || 'device_unknown');
@@ -625,10 +628,10 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
625
628
  this.on('message', updateLast);
626
629
  this.on('iris', updateLast);
627
630
 
628
- const KEEPALIVE_FOREGROUND_MS = (this.initOptions && this.initOptions.keepaliveForegroundMs) ? this.initOptions.keepaliveForegroundMs : 30000;
629
- const MESSAGE_SYNC_REFRESH_MS = (this.initOptions && this.initOptions.messageSyncRefreshMs) ? this.initOptions.messageSyncRefreshMs : 60000;
630
- const TRAFFIC_INACTIVITY_MS = (this.initOptions && this.initOptions.trafficInactivityMs) ? this.initOptions.trafficInactivityMs : 90000;
631
- const HEARTBEAT_MS = (this.initOptions && this.initOptions.heartbeatMs) ? this.initOptions.heartbeatMs : 30000;
631
+ const KEEPALIVE_FOREGROUND_MS = (this.initOptions && this.initOptions.keepaliveForegroundMs) ? this.initOptions.keepaliveForegroundMs : 15000;
632
+ const MESSAGE_SYNC_REFRESH_MS = (this.initOptions && this.initOptions.messageSyncRefreshMs) ? this.initOptions.messageSyncRefreshMs : 45000;
633
+ const TRAFFIC_INACTIVITY_MS = (this.initOptions && this.initOptions.trafficInactivityMs) ? this.initOptions.trafficInactivityMs : 60000;
634
+ const HEARTBEAT_MS = (this.initOptions && this.initOptions.heartbeatMs) ? this.initOptions.heartbeatMs : 15000;
632
635
  const HEARTBEAT_NUMERIC_TOPICS = this.connection?.clientInfo?.subscribeTopics || [88, 135, 149, 150, 133, 146];
633
636
 
634
637
  try {
@@ -800,6 +803,17 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
800
803
  } catch(e) {}
801
804
  } catch (error) {}
802
805
  this._setupMessageHandlers();
806
+
807
+ // --- START: Active MQTT query keepalive ---
808
+ // Start a periodic "active query" that touches PUBSUB and REALTIME_SUB topics
809
+ // to keep the connection considered alive by the server, especially across long idle periods.
810
+ try {
811
+ // call wrapper which will set/clear the timer idempotently
812
+ this._startActiveQueryKeepalive();
813
+ } catch (e) {
814
+ this.realtimeDebug('[ACTIVE_QUERY] failed to start:', e?.message || e);
815
+ }
816
+ // --- END: Active MQTT query keepalive ---
803
817
  }
804
818
 
805
819
  /**
@@ -1264,6 +1278,12 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
1264
1278
  clearInterval(this._mqttSessionPersistIntervalId);
1265
1279
  this._mqttSessionPersistIntervalId = null;
1266
1280
  }
1281
+
1282
+ // Clear the active keepalive/query timer if running
1283
+ if (this._activeKeepaliveTimer) {
1284
+ clearInterval(this._activeKeepaliveTimer);
1285
+ this._activeKeepaliveTimer = null;
1286
+ }
1267
1287
  } catch (e) {}
1268
1288
  // persist final session snapshot
1269
1289
  try { this._persistMqttSession(); } catch (e) {}
@@ -1328,5 +1348,70 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
1328
1348
  },
1329
1349
  });
1330
1350
  }
1351
+
1352
+ /**
1353
+ * Start an "active query" keepalive loop
1354
+ * - This sends a lightweight PUBSUB foreground pulse and a REALTIME_SUB reaffirmation
1355
+ * on a periodic basis to keep the server-side connection state active.
1356
+ *
1357
+ * Behavior & protections:
1358
+ * - Idle-aware: will skip sending if client received traffic within idleThresholdMs (to avoid unnecessary traffic).
1359
+ * - Interval configurable via initOptions.activeKeepaliveMs (default 45s).
1360
+ * - GraphQL subs reaffirmation uses initOptions.graphQlSubs or defaultGraphQlSubs.
1361
+ */
1362
+ _startActiveQueryKeepalive() {
1363
+ try {
1364
+ // Clear any existing timer idempotently
1365
+ if (this._activeKeepaliveTimer) {
1366
+ clearInterval(this._activeKeepaliveTimer);
1367
+ this._activeKeepaliveTimer = null;
1368
+ }
1369
+
1370
+ const ms = (this.initOptions && this.initOptions.activeKeepaliveMs) ? this.initOptions.activeKeepaliveMs : 25000;
1371
+ const idleThresholdMs = (this.initOptions && this.initOptions.activeKeepaliveIdleThresholdMs) ? this.initOptions.activeKeepaliveIdleThresholdMs : 15000;
1372
+
1373
+ // small wrapper to avoid unhandled rejection inside setInterval
1374
+ this._activeKeepaliveTimer = setInterval(async () => {
1375
+ try {
1376
+ if (!this.commands) return;
1377
+
1378
+ // Do not send keepalive if we received traffic recently — avoids noisy pulses during active use.
1379
+ const idle = Date.now() - (this._lastMessageAt || 0);
1380
+ if (idle < idleThresholdMs) {
1381
+ // skip sending if not idle enough
1382
+ return;
1383
+ }
1384
+
1385
+ // 1) PUBSUB "foreground pulse" with a tiny timestamp payload (safe, no side-effects)
1386
+ try {
1387
+ await this.commands.updateSubscriptions({
1388
+ topic: constants_1.Topics.PUBSUB,
1389
+ data: { foreground: true, keepalive_ts: Date.now() }
1390
+ });
1391
+ } catch (e) {
1392
+ // log but continue to attempt realtime-sub reaffirmation
1393
+ this.realtimeDebug('[ACTIVE_QUERY] PUBSUB foreground pulse failed:', e?.message || e);
1394
+ }
1395
+
1396
+ // 2) REALTIME_SUB reaffirmation of GraphQL subs (lightweight)
1397
+ try {
1398
+ const subs = (this.initOptions && this.initOptions.graphQlSubs && this.initOptions.graphQlSubs.length) ? this.initOptions.graphQlSubs : this.defaultGraphQlSubs;
1399
+ await this.commands.updateSubscriptions({
1400
+ topic: constants_1.Topics.REALTIME_SUB,
1401
+ data: { sub: subs, keepalive_ts: Date.now() }
1402
+ });
1403
+ } catch (e) {
1404
+ this.realtimeDebug('[ACTIVE_QUERY] REALTIME_SUB reaffirmation failed:', e?.message || e);
1405
+ }
1406
+
1407
+ this.realtimeDebug('[ACTIVE_QUERY] keepalive query sent (idle ms: ' + idle + ')');
1408
+ } catch (e) {
1409
+ this.realtimeDebug('[ACTIVE_QUERY] unexpected error in keepalive loop:', e?.message || e);
1410
+ }
1411
+ }, ms);
1412
+ } catch (e) {
1413
+ this.realtimeDebug('[ACTIVE_QUERY] could not start keepalive timer:', e?.message || e);
1414
+ }
1415
+ }
1331
1416
  }
1332
1417
  exports.RealtimeClient = RealtimeClient;
@@ -77,7 +77,7 @@ class Utils {
77
77
  }
78
78
 
79
79
  static formatWebUserAgent(devicePayload, build, appUserAgent) {
80
- return `Mozilla/5.0 (Linux; Android ${devicePayload.android_release}; ${devicePayload.model} Build/${build}; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36 ${appUserAgent}`;
80
+ return `Mozilla/5.0 (Linux; Android ${devicePayload.android_release}; ${devicePayload.model} Build/${build}; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.139 Mobile Safari/537.36 ${appUserAgent}`;
81
81
  }
82
82
 
83
83
  static parseUserId(userIdOrUsername) {
@@ -190,7 +190,7 @@ class Utils {
190
190
  }
191
191
 
192
192
  static createUserAgentFromDevice(device) {
193
- return `Instagram 401.0.0.48.79 Android (${device.android_version}/${device.android_release}; ${device.dpi}dpi; ${device.resolution}; ${device.manufacturer}; ${device.model}; ${device.device}; ${device.cpu})`;
193
+ return `Instagram 420.0.0.42.95 Android (${device.android_version}/${device.android_release}; ${device.dpi}dpi; ${device.resolution}; ${device.manufacturer}; ${device.model}; ${device.device}; ${device.cpu})`;
194
194
  }
195
195
 
196
196
  // ========================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodejs-insta-private-api-mqtt",
3
- "version": "1.3.45",
3
+ "version": "1.3.47",
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": {