nodejs-insta-private-api-mqtt 1.3.35 → 1.3.36
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.
- package/dist/realtime/realtime.client.js +145 -1
- package/package.json +1 -1
- package/LICENSE +0 -21
|
@@ -105,6 +105,10 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
105
105
|
this._reconnectDebounceMs = 500;
|
|
106
106
|
this._reconnectTimeoutId = null;
|
|
107
107
|
|
|
108
|
+
// MQTT session tracking & persistence
|
|
109
|
+
this._mqttSessionId = null; // actual server-provided mqtt session id (string)
|
|
110
|
+
this._mqttSessionPersistIntervalId = null; // periodic persist interval handler
|
|
111
|
+
|
|
108
112
|
// Persisted identity items that must survive reconnects:
|
|
109
113
|
// - clientMqttSessionId must NOT be re-generated each connect
|
|
110
114
|
// - _clientContext for EnhancedDirectCommands (for message identity)
|
|
@@ -488,6 +492,8 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
488
492
|
this.constructConnection();
|
|
489
493
|
const { MQTToTClient } = require("../mqttot");
|
|
490
494
|
const { compressDeflate } = require("../shared");
|
|
495
|
+
const fs = require('fs');
|
|
496
|
+
const path = require('path');
|
|
491
497
|
|
|
492
498
|
// Create the MQTT client used by the runtime.
|
|
493
499
|
// requirePayload set to false to avoid treating empty CONNACK payload as fatal.
|
|
@@ -508,7 +514,18 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
508
514
|
try {
|
|
509
515
|
this._mqtt.on('connect', async () => {
|
|
510
516
|
this.realtimeDebug('[MQTT] client emitted connect');
|
|
511
|
-
try {
|
|
517
|
+
try {
|
|
518
|
+
// After normal after-connect handlers, try extract session id and persist it
|
|
519
|
+
await this._afterConnectHandlers();
|
|
520
|
+
} catch (e) {
|
|
521
|
+
this.realtimeDebug('[MQTT] afterConnect error', e?.message || e);
|
|
522
|
+
}
|
|
523
|
+
// After everything, attempt to detect and persist MQTT session id
|
|
524
|
+
try {
|
|
525
|
+
await this._onMqttConnected();
|
|
526
|
+
} catch (e) {
|
|
527
|
+
this.realtimeDebug('[MQTT] _onMqttConnected error', e?.message || e);
|
|
528
|
+
}
|
|
512
529
|
});
|
|
513
530
|
} catch (e) {}
|
|
514
531
|
try {
|
|
@@ -516,6 +533,9 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
516
533
|
this._mqtt.on('close', async () => {
|
|
517
534
|
this.realtimeDebug('[MQTT] client close event');
|
|
518
535
|
this._lastMessageAt = Date.now();
|
|
536
|
+
// persist session (last state) on close
|
|
537
|
+
try { await this._persistMqttSession(); } catch (e) {}
|
|
538
|
+
this.emit('mqtt_disconnected');
|
|
519
539
|
if (this._reconnectTimeoutId) clearTimeout(this._reconnectTimeoutId);
|
|
520
540
|
this._reconnectTimeoutId = setTimeout(async () => {
|
|
521
541
|
try { await this._attemptReconnectSafely(); } catch (e) {}
|
|
@@ -526,6 +546,7 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
526
546
|
// handle error -> schedule reconnect attempt with debounce
|
|
527
547
|
this._mqtt.on('error', (err) => {
|
|
528
548
|
this.realtimeDebug('[MQTT] client error:', err?.message || err);
|
|
549
|
+
this.emit('mqtt_error', err);
|
|
529
550
|
if (this._reconnectTimeoutId) clearTimeout(this._reconnectTimeoutId);
|
|
530
551
|
this._reconnectTimeoutId = setTimeout(async () => {
|
|
531
552
|
try { await this._attemptReconnectSafely(); } catch (e) {}
|
|
@@ -545,6 +566,7 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
545
566
|
|
|
546
567
|
// Notify higher-level code that we are connected
|
|
547
568
|
this.emit('connected');
|
|
569
|
+
this.emit('mqtt_connected');
|
|
548
570
|
|
|
549
571
|
// WATCHDOG / KEEPALIVE / TRAFFIC MONITOR
|
|
550
572
|
try {
|
|
@@ -684,6 +706,121 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
684
706
|
this._setupMessageHandlers();
|
|
685
707
|
}
|
|
686
708
|
|
|
709
|
+
/**
|
|
710
|
+
* Attempt to detect server-provided MQTT session id and persist it.
|
|
711
|
+
* This method is defensive: it tries multiple places on the mqtt client object.
|
|
712
|
+
*/
|
|
713
|
+
async _onMqttConnected() {
|
|
714
|
+
try {
|
|
715
|
+
let found = null;
|
|
716
|
+
try {
|
|
717
|
+
const mqtt = this._mqtt;
|
|
718
|
+
if (mqtt) {
|
|
719
|
+
// try common accessor first
|
|
720
|
+
if (typeof mqtt.getSessionId === 'function') {
|
|
721
|
+
try { found = mqtt.getSessionId(); } catch (e) {}
|
|
722
|
+
}
|
|
723
|
+
// try common property names (defensive)
|
|
724
|
+
if (!found && mqtt.sessionId) found = mqtt.sessionId;
|
|
725
|
+
if (!found && mqtt._sessionId) found = mqtt._sessionId;
|
|
726
|
+
// some clients keep last connack info
|
|
727
|
+
if (!found && mqtt.lastConnack && mqtt.lastConnack.sessionId) found = mqtt.lastConnack.sessionId;
|
|
728
|
+
if (!found && mqtt.connack && mqtt.connack.sessionId) found = mqtt.connack.sessionId;
|
|
729
|
+
// fallback to connection.clientInfo.clientMqttSessionId (local id)
|
|
730
|
+
if (!found && this.connection && this.connection.clientInfo && this.connection.clientInfo.clientMqttSessionId) {
|
|
731
|
+
try { found = String(this.connection.clientInfo.clientMqttSessionId); } catch (e) {}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
} catch (e) {}
|
|
735
|
+
// If no server-provided id was found, fall back to the persistent client id (if present) or 'boot'
|
|
736
|
+
if (!found) {
|
|
737
|
+
if (this._clientMqttSessionId) {
|
|
738
|
+
try {
|
|
739
|
+
found = String(this._clientMqttSessionId);
|
|
740
|
+
this.realtimeDebug('[MQTT] No server mqttSessionId yet — falling back to clientMqttSessionId.');
|
|
741
|
+
} catch (e) {
|
|
742
|
+
// ignore and keep found null
|
|
743
|
+
}
|
|
744
|
+
} else {
|
|
745
|
+
// final fallback
|
|
746
|
+
found = 'boot';
|
|
747
|
+
this.realtimeDebug('[MQTT] No mqttSessionId available — using boot fallback.');
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
if (found) {
|
|
751
|
+
this._mqttSessionId = String(found);
|
|
752
|
+
this.realtimeDebug(`[MQTT] detected mqttSessionId: ${this._mqttSessionId}`);
|
|
753
|
+
// emit event for consumers
|
|
754
|
+
try { this.emit('mqtt_session', this._mqttSessionId); } catch (e) {}
|
|
755
|
+
// persist it right away
|
|
756
|
+
try { await this._persistMqttSession(); } catch (e) { this.realtimeDebug('[MQTT] persist after connect failed', e?.message || e); }
|
|
757
|
+
// start periodic persist if not already (persist every 30s)
|
|
758
|
+
if (!this._mqttSessionPersistIntervalId) {
|
|
759
|
+
try {
|
|
760
|
+
this._mqttSessionPersistIntervalId = setInterval(() => {
|
|
761
|
+
try { this._persistMqttSession(); } catch (e) {}
|
|
762
|
+
}, 30 * 1000); // every 30s
|
|
763
|
+
} catch (e) {}
|
|
764
|
+
}
|
|
765
|
+
} else {
|
|
766
|
+
this.realtimeDebug('[MQTT] mqttSessionId not found on client after connect (will attempt again on subsequent connects)');
|
|
767
|
+
}
|
|
768
|
+
} catch (e) {
|
|
769
|
+
this.realtimeDebug('[MQTT] _onMqttConnected fatal', e?.message || e);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* Persist mqtt session details locally and via attached auth helper if available.
|
|
775
|
+
* Writes ./authinfo_instagram/mqtt-session.json as a local backup.
|
|
776
|
+
*/
|
|
777
|
+
async _persistMqttSession() {
|
|
778
|
+
try {
|
|
779
|
+
const fs = require('fs');
|
|
780
|
+
const path = require('path');
|
|
781
|
+
const folder = './authinfo_instagram';
|
|
782
|
+
try {
|
|
783
|
+
if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true });
|
|
784
|
+
} catch (e) {}
|
|
785
|
+
|
|
786
|
+
// IMPORTANT: prefer server-provided mqtt session id when available.
|
|
787
|
+
// Fallback order:
|
|
788
|
+
// 1) this._mqttSessionId (server-provided)
|
|
789
|
+
// 2) this._clientMqttSessionId (client-generated persistent id)
|
|
790
|
+
// 3) 'boot'
|
|
791
|
+
const obj = {
|
|
792
|
+
sessionId: this._mqttSessionId || null,
|
|
793
|
+
mqttSessionId: this._mqttSessionId ? String(this._mqttSessionId) : (this._clientMqttSessionId ? String(this._clientMqttSessionId) : 'boot'),
|
|
794
|
+
lastConnected: new Date().toISOString(),
|
|
795
|
+
userId: String(this.ig?.state?.cookieUserId || this.ig?.state?.userId || '')
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
// If an auth helper supports saveMqttSession, call that first (so it can save to the canonical auth state)
|
|
799
|
+
try {
|
|
800
|
+
if (this._attachedAuthState && typeof this._attachedAuthState.saveMqttSession === 'function') {
|
|
801
|
+
try {
|
|
802
|
+
// Many helpers expect the realtime client instance
|
|
803
|
+
await this._attachedAuthState.saveMqttSession(this);
|
|
804
|
+
this.realtimeDebug('[MQTT] authState.saveMqttSession called');
|
|
805
|
+
} catch (e) {
|
|
806
|
+
this.realtimeDebug('[MQTT] authState.saveMqttSession failed', e?.message || e);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
} catch (e) {}
|
|
810
|
+
|
|
811
|
+
// Always write local backup file
|
|
812
|
+
try {
|
|
813
|
+
fs.writeFileSync(path.join(folder, 'mqtt-session.json'), JSON.stringify(obj, null, 2));
|
|
814
|
+
this.realtimeDebug('[MQTT] mqtt-session.json written locally');
|
|
815
|
+
} catch (e) {
|
|
816
|
+
this.realtimeDebug('[MQTT] failed writing mqtt-session.json', e?.message || e);
|
|
817
|
+
}
|
|
818
|
+
} catch (e) {
|
|
819
|
+
// swallow errors to not break main flow
|
|
820
|
+
this.realtimeDebug('[MQTT] _persistMqttSession error', e?.message || e);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
687
824
|
/**
|
|
688
825
|
* _attemptReconnectSafely()
|
|
689
826
|
* - Ensure only a single reconnect flow runs at once.
|
|
@@ -892,7 +1029,14 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
892
1029
|
clearInterval(this._trafficWatchdog);
|
|
893
1030
|
this._trafficWatchdog = null;
|
|
894
1031
|
}
|
|
1032
|
+
// clear periodic mqtt persist
|
|
1033
|
+
if (this._mqttSessionPersistIntervalId) {
|
|
1034
|
+
clearInterval(this._mqttSessionPersistIntervalId);
|
|
1035
|
+
this._mqttSessionPersistIntervalId = null;
|
|
1036
|
+
}
|
|
895
1037
|
} catch (e) {}
|
|
1038
|
+
// persist final session snapshot
|
|
1039
|
+
try { this._persistMqttSession(); } catch (e) {}
|
|
896
1040
|
return this.mqtt?.disconnect() ?? Promise.resolve();
|
|
897
1041
|
}
|
|
898
1042
|
|
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.36",
|
|
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": {
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 KunBORUTO20(INSTAGRAM MQTT )
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|