nodejs-insta-private-api-mqtt 1.3.42 → 1.3.44

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/README.md CHANGED
@@ -814,6 +814,140 @@ await ig.direct.sendText({ thread_ids: [threadId], text: 'Hello' });
814
814
  | `presence` | User presence update |
815
815
  | `error` | Connection error |
816
816
 
817
+ ### Advanced Real-time Events (instagram_mqtt compatible)
818
+
819
+ These events provide deeper access to Instagram's MQTT protocol. They were added for full compatibility with the instagram_mqtt library.
820
+
821
+ | Event | Description |
822
+ |-------|-------------|
823
+ | `realtimeSub` | Raw realtime subscription data (all MQTT messages) |
824
+ | `direct` | Direct message events with parsed data |
825
+ | `subscription` | Legacy subscription event (backwards compatible) |
826
+ | `directTyping` | When someone is typing in a DM thread |
827
+ | `appPresence` | User online/offline status updates |
828
+ | `directStatus` | DM thread status changes |
829
+ | `liveWave` | Instagram Live wave notifications |
830
+ | `liveRealtimeComments` | Real-time comments on Instagram Live |
831
+ | `liveTypingIndicator` | Typing indicator in Live comments |
832
+ | `mediaFeedback` | Media engagement feedback |
833
+ | `clientConfigUpdate` | Client configuration updates |
834
+
835
+ #### Using the realtimeSub Event
836
+
837
+ The `realtimeSub` event gives you access to all raw MQTT messages. This is useful for debugging or implementing custom message handling:
838
+
839
+ ```javascript
840
+ realtime.on('realtimeSub', ({ data, topic }) => {
841
+ console.log('Raw MQTT data received:', data);
842
+ console.log('Topic:', topic);
843
+ });
844
+ ```
845
+
846
+ #### Using the direct Event
847
+
848
+ The `direct` event provides parsed direct message updates with automatic JSON parsing of nested values:
849
+
850
+ ```javascript
851
+ realtime.on('direct', (data) => {
852
+ console.log('Direct update:', data);
853
+
854
+ // data.op contains the operation type (e.g., 'add', 'replace', 'remove')
855
+ // data.path contains the affected path
856
+ // data.value contains the parsed message data
857
+
858
+ if (data.op === 'add' && data.value) {
859
+ console.log('New message:', data.value.text);
860
+ }
861
+ });
862
+ ```
863
+
864
+ #### Using QueryID-based Events
865
+
866
+ These events are automatically emitted when Instagram sends specific subscription updates:
867
+
868
+ ```javascript
869
+ // Listen for typing indicators
870
+ realtime.on('directTyping', (data) => {
871
+ console.log('User is typing:', data);
872
+ });
873
+
874
+ // Listen for presence updates (online/offline status)
875
+ realtime.on('appPresence', (data) => {
876
+ console.log('Presence update:', data);
877
+ });
878
+
879
+ // Listen for DM status changes
880
+ realtime.on('directStatus', (data) => {
881
+ console.log('Direct status changed:', data);
882
+ });
883
+
884
+ // Listen for Instagram Live comments
885
+ realtime.on('liveRealtimeComments', (data) => {
886
+ console.log('Live comment:', data);
887
+ });
888
+ ```
889
+
890
+ #### Complete Example: Multi-Event Listener
891
+
892
+ Here's a complete example showing how to listen to multiple events:
893
+
894
+ ```javascript
895
+ const { IgApiClient, RealtimeClient, useMultiFileAuthState } = require('nodejs-insta-private-api-mqtt');
896
+
897
+ async function startAdvancedBot() {
898
+ const ig = new IgApiClient();
899
+ const auth = await useMultiFileAuthState('./auth_info_ig');
900
+
901
+ ig.state.usePresetDevice('Samsung Galaxy S25 Ultra');
902
+
903
+ const realtime = new RealtimeClient(ig);
904
+
905
+ // Standard message handling
906
+ realtime.on('message_live', (msg) => {
907
+ console.log(`[${msg.username}]: ${msg.text}`);
908
+ });
909
+
910
+ // Advanced: Raw MQTT data (useful for debugging)
911
+ realtime.on('realtimeSub', ({ data }) => {
912
+ console.log('[Debug] Raw MQTT:', JSON.stringify(data).substring(0, 200));
913
+ });
914
+
915
+ // Direct message updates with parsed data
916
+ realtime.on('direct', (data) => {
917
+ if (data.op === 'add') {
918
+ console.log('[Direct] New item added');
919
+ }
920
+ });
921
+
922
+ // Typing indicators
923
+ realtime.on('directTyping', (data) => {
924
+ console.log('[Typing] Someone is typing...');
925
+ });
926
+
927
+ // User presence (online/offline)
928
+ realtime.on('appPresence', (data) => {
929
+ console.log('[Presence] User status changed');
930
+ });
931
+
932
+ // Login and connect
933
+ if (!auth.hasSession()) {
934
+ await ig.login({
935
+ username: 'your_username',
936
+ password: 'your_password'
937
+ });
938
+ await auth.saveCreds(ig);
939
+ } else {
940
+ await auth.loadCreds(ig);
941
+ }
942
+
943
+ await realtime.startRealTimeListener();
944
+
945
+ console.log('Advanced bot with full MQTT events is running!');
946
+ }
947
+
948
+ startAdvancedBot().catch(console.error);
949
+ ```
950
+
817
951
  ---
818
952
 
819
953
  ## Important Notes
@@ -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 = '412.0.0.35.87';
6
+ exports.INSTAGRAM_VERSION = '414.0.0.40.83';
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 ***
@@ -1,15 +1,36 @@
1
1
  "use strict";
2
+ /**
3
+ * RealtimeSubMixin - ENHANCED VERSION
4
+ *
5
+ * This file has been modified to include all MQTT features from instagram_mqtt library.
6
+ *
7
+ * CHANGES MADE (from instagram_mqtt compatibility):
8
+ * 1. Added import for subscriptions (QueryIDs) - was MISSING
9
+ * 2. Added client.mqtt.listen() approach for REALTIME_SUB topic - was MISSING
10
+ * 3. Added 'realtimeSub' event emission - was MISSING (only had 'subscription')
11
+ * 4. Added 'direct' topic processing - was MISSING
12
+ * 5. Added emitDirectEvent() method - was MISSING
13
+ * 6. Added QueryIDs-based event emission (directTyping, appPresence, etc.) - was MISSING
14
+ *
15
+ * PRESERVED:
16
+ * - Original 'subscription' event emission (for backwards compatibility)
17
+ * - Original on('message') approach with topicMap (extended, not replaced)
18
+ * - All existing retry logic and error handling
19
+ */
2
20
  Object.defineProperty(exports, "__esModule", { value: true });
3
21
  exports.RealtimeSubMixin = void 0;
4
22
  const mixin_1 = require("./mixin");
5
23
  const constants_1 = require("../../constants");
6
24
  const shared_1 = require("../../shared");
25
+ // ADDED: Import subscriptions for QueryIDs (was MISSING in nodejs-insta-private-api-mqtt)
26
+ const subscriptions_1 = require("../subscriptions");
7
27
  const mqtts_1 = require("mqtts");
28
+
8
29
  class RealtimeSubMixin extends mixin_1.Mixin {
9
30
  apply(client) {
10
31
  (0, mixin_1.hook)(client, 'connect', {
11
32
  post: async () => {
12
- // Wait for MQTT client to be ready
33
+ // Wait for MQTT client to be ready (PRESERVED from original)
13
34
  let retries = 0;
14
35
  while (!client.mqtt && retries < 50) {
15
36
  await new Promise(r => setTimeout(r, 100));
@@ -18,6 +39,33 @@ class RealtimeSubMixin extends mixin_1.Mixin {
18
39
  if (!client.mqtt) {
19
40
  throw new mqtts_1.IllegalStateError('No mqtt client created after retries');
20
41
  }
42
+
43
+ // ADDED: Use client.mqtt.listen() for REALTIME_SUB topic (from instagram_mqtt)
44
+ // This is the approach used by instagram_mqtt for handling realtime subscriptions
45
+ if (client.mqtt.listen) {
46
+ client.mqtt.listen({
47
+ topic: constants_1.Topics.REALTIME_SUB.id,
48
+ transformer: async ({ payload }) => {
49
+ try {
50
+ return constants_1.Topics.REALTIME_SUB.parser.parseMessage(
51
+ constants_1.Topics.REALTIME_SUB,
52
+ await (0, shared_1.tryUnzipAsync)(payload)
53
+ );
54
+ } catch (err) {
55
+ // If transformer fails, return null so handler can skip
56
+ console.warn('[RealtimeSubMixin] transformer parse failed:', err?.message || err);
57
+ return null;
58
+ }
59
+ },
60
+ }, data => {
61
+ if (data) {
62
+ // ADDED: Call the instagram_mqtt compatible handler
63
+ this.handleRealtimeSubFromListen(client, data);
64
+ }
65
+ });
66
+ }
67
+
68
+ // PRESERVED: Original on('message') approach with topicMap (for backwards compatibility)
21
69
  client.mqtt.on('message', async (msg) => {
22
70
  const topicMap = client.mqtt?.topicMap;
23
71
  const topic = topicMap?.get(msg.topic);
@@ -40,13 +88,91 @@ class RealtimeSubMixin extends mixin_1.Mixin {
40
88
  },
41
89
  });
42
90
  }
91
+
92
+ /**
93
+ * ADDED: Handler compatible with instagram_mqtt's listen() approach
94
+ * This method handles data from client.mqtt.listen() and emits instagram_mqtt compatible events
95
+ *
96
+ * @param {Object} client - The realtime client instance
97
+ * @param {Object} param1 - The parsed data object containing { data, topic }
98
+ */
99
+ handleRealtimeSubFromListen(client, { data, topic: messageTopic }) {
100
+ const { message } = data;
101
+
102
+ // ADDED: Emit 'realtimeSub' event (was MISSING - this is what instagram_mqtt does)
103
+ client.emit('realtimeSub', { data, topic: messageTopic });
104
+
105
+ // ADDED: Process message based on type (was MISSING)
106
+ if (typeof message === 'string') {
107
+ // If message is a string, parse it and emit direct event
108
+ this.emitDirectEvent(client, JSON.parse(message));
109
+ }
110
+ else if (message) {
111
+ const { topic, payload, json } = message;
112
+ switch (topic) {
113
+ case 'direct': {
114
+ // ADDED: Handle 'direct' topic specifically (was MISSING)
115
+ this.emitDirectEvent(client, json);
116
+ break;
117
+ }
118
+ default: {
119
+ // ADDED: Emit QueryID-based events (was MISSING)
120
+ // This emits events like 'directTyping', 'appPresence', 'directStatus', etc.
121
+ const entries = Object.entries(subscriptions_1.QueryIDs);
122
+ const query = entries.find(e => e[1] === topic);
123
+ if (query) {
124
+ client.emit(query[0], json || payload);
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
130
+
131
+ /**
132
+ * ADDED: Method to emit direct events (was MISSING from nodejs-insta-private-api-mqtt)
133
+ * This method parses string values in parsed.data and emits 'direct' event for each
134
+ *
135
+ * @param {Object} client - The realtime client instance
136
+ * @param {Object} parsed - The parsed message object containing data array
137
+ */
138
+ emitDirectEvent(client, parsed) {
139
+ if (!parsed || !parsed.data || !Array.isArray(parsed.data)) {
140
+ return;
141
+ }
142
+
143
+ parsed.data = parsed.data.map((e) => {
144
+ if (typeof e.value === 'string') {
145
+ try {
146
+ e.value = JSON.parse(e.value);
147
+ } catch (parseErr) {
148
+ // If parsing fails, keep original value
149
+ console.warn('[RealtimeSubMixin] emitDirectEvent JSON parse failed:', parseErr?.message);
150
+ }
151
+ }
152
+ return e;
153
+ });
154
+
155
+ // Emit 'direct' event for each data item
156
+ parsed.data.forEach((data) => client.emit('direct', data));
157
+ }
158
+
159
+ /**
160
+ * PRESERVED: Original handler for on('message') approach (for backwards compatibility)
161
+ * This emits the 'subscription' event that existing code may depend on
162
+ *
163
+ * @param {Object} client - The realtime client instance
164
+ * @param {Object} topic - The topic object from topicMap
165
+ * @param {Object} data - The parsed message data
166
+ */
43
167
  handleRealtimeSub(client, topic, data) {
168
+ // PRESERVED: Emit 'subscription' event (original behavior)
44
169
  client.emit('subscription', {
45
170
  query: topic.path,
46
171
  data: data,
47
172
  topic: topic,
48
173
  });
49
174
  }
175
+
50
176
  get name() {
51
177
  return 'Realtime Sub';
52
178
  }
@@ -339,7 +339,7 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
339
339
  ? this.ig.state.appUserAgent
340
340
  : typeof this.ig.state.deviceString === 'string'
341
341
  ? this.ig.state.deviceString
342
- : 'Instagram 155.0.0.37.107 Android';
342
+ : 'Instagram 414.0.0.40.83 Android';
343
343
 
344
344
  // deviceId / phoneId fallback handling (string coercion)
345
345
  const deviceId = String(this.ig.state.phoneId || this.ig.state.deviceId || 'device_unknown');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodejs-insta-private-api-mqtt",
3
- "version": "1.3.42",
3
+ "version": "1.3.44",
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": {