nodejs-insta-private-api-mqtt 1.1.9 → 1.2.10

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
@@ -173,51 +173,64 @@ console.log('Build:', info.build);
173
173
  console.log('User Agent:', info.userAgent);
174
174
  ```
175
175
 
176
- ### Complete Bot Example with Custom Device
176
+ ### 178. Complete Bot Example with Instant MQTT Boot
177
+
178
+ This example demonstrates how to build a production-ready bot that restores its session and connects to MQTT instantly upon startup.
177
179
 
178
180
  ```javascript
179
- const { IgApiClient, RealtimeClient } = require('nodejs-insta-private-api-mqtt');
180
- const fs = require('fs');
181
+ const { IgApiClient, RealtimeClient, useMultiFileAuthState } = require('nodejs-insta-private-api-mqtt');
181
182
 
182
183
  async function startBot() {
183
184
  const ig = new IgApiClient();
184
185
 
185
- // Step 1: Set your preferred device BEFORE login
186
- ig.state.usePresetDevice('Samsung Galaxy S25 Ultra');
187
-
188
- console.log('Device configured:', ig.state.deviceString);
189
- console.log('User Agent:', ig.state.appUserAgent);
190
-
191
- // Step 2: Login
192
- await ig.login({
193
- username: process.env.IG_USERNAME,
194
- password: process.env.IG_PASSWORD
195
- });
196
-
197
- console.log('Login successful!');
186
+ // 1. Initialize the multi-file auth state (Baileys style)
187
+ // This folder stores your credentials, cookies, and MQTT session
188
+ const auth = await useMultiFileAuthState('./auth_info_ig');
198
189
 
199
- // Step 3: Save session (device info is included)
200
- const session = await ig.state.serialize();
201
- fs.writeFileSync('session.json', JSON.stringify(session, null, 2));
190
+ // 2. Setup your device emulation
191
+ ig.state.usePresetDevice('Samsung Galaxy S25 Ultra');
202
192
 
203
- // Step 4: Connect to real-time messaging
193
+ // 3. Initialize the RealtimeClient
194
+ // IMPORTANT: Because we modified the constructor, this will AUTOMATICALLY
195
+ // detect the session in ./auth_info_ig and start MQTT in the background.
204
196
  const realtime = new RealtimeClient(ig);
205
- const inbox = await ig.direct.getInbox();
206
-
207
- await realtime.connect({
208
- graphQlSubs: ['ig_sub_direct', 'ig_sub_direct_v2_message_sync'],
209
- skywalkerSubs: ['presence_subscribe', 'typing_subscribe'],
210
- irisData: inbox
197
+
198
+ // 4. Set up your event listeners
199
+ realtime.on('connected', () => {
200
+ console.log('🚀 Bot is online and MQTT is connected!');
211
201
  });
212
-
213
- console.log('Bot is online with Samsung Galaxy S25 Ultra emulation!');
214
-
215
- realtime.on('message', (data) => {
216
- console.log('New message:', data.message?.text);
202
+
203
+ realtime.on('message_live', async (msg) => {
204
+ console.log(`📩 [${msg.username}]: ${msg.text}`);
205
+
206
+ // Simple auto-reply logic
207
+ if (msg.text.toLowerCase() === 'ping') {
208
+ await realtime.directCommands.sendTextViaRealtime(msg.thread_id, 'pong! 🏓');
209
+ }
217
210
  });
218
-
219
- // Keep running
220
- await new Promise(() => {});
211
+
212
+ // 5. Handle the initial "Pairing" (only happens once)
213
+ if (!auth.hasSession()) {
214
+ console.log('No session found. Please login to pair your account...');
215
+
216
+ await ig.login({
217
+ username: 'your_username',
218
+ password: 'your_password'
219
+ });
220
+
221
+ // Save credentials for the next boot
222
+ await auth.saveCreds(ig);
223
+
224
+ // Start the realtime sync for the first time
225
+ await realtime.startRealTimeListener();
226
+
227
+ // Save the MQTT state so we can boot instantly next time
228
+ await auth.saveMqttSession(realtime);
229
+
230
+ console.log('✅ Pairing successful! Next time you run this, it will boot INSTANTLY.');
231
+ } else {
232
+ console.log('✨ Existing session detected. Instant MQTT boot sequence initiated...');
233
+ }
221
234
  }
222
235
 
223
236
  startBot().catch(console.error);
@@ -250,100 +263,109 @@ startBot().catch(console.error);
250
263
 
251
264
  ---
252
265
 
253
- ## NEW: useMultiFileAuthState (v5.60.2)
266
+ ## 🚀 NEW: Instant MQTT Connection (v5.70.0)
254
267
 
255
- This feature provides **Baileys-style multi-file session persistence** for Instagram. Instead of storing everything in a single `session.json`, the session is split across multiple files for better organization, security, and reliability.
268
+ We've completely overhauled how the MQTT connection works. You no longer need to manually manage connection states every time your bot restarts. Just like **Baileys**, if a session is present in the default folder, the library takes care of everything for you.
256
269
 
257
- ### Session Files Structure
270
+ ### Why this is a game changer:
271
+ - **Zero Configuration**: No need to pass IRIS data or subscription topics manually on every boot.
272
+ - **Background Startup**: The MQTT connection starts the moment you create the `RealtimeClient`.
273
+ - **Session Persistence**: Cookies, device info, and MQTT state are managed automatically.
258
274
 
275
+ ### 🔌 How to use Instant Boot
276
+
277
+ Once you've linked your account (see the setup section below), your main script can be as simple as this:
278
+
279
+ ```javascript
280
+ const { IgApiClient, RealtimeClient } = require('nodejs-insta-private-api-mqtt');
281
+
282
+ // 1. Initialize the client
283
+ const ig = new IgApiClient();
284
+
285
+ // 2. That's it!
286
+ // If ./auth_info_ig exists, MQTT starts background connection immediately.
287
+ const realtime = new RealtimeClient(ig);
288
+
289
+ // 3. Listen for events
290
+ realtime.on('connected', () => {
291
+ console.log('✅ MQTT is live and kicking!');
292
+ });
293
+
294
+ realtime.on('message_live', (msg) => {
295
+ console.log(`📩 New message from ${msg.username}: ${msg.text}`);
296
+ });
297
+
298
+ realtime.on('error', (err) => {
299
+ console.error('❌ MQTT Connection issue:', err.message);
300
+ });
259
301
  ```
260
- auth_info_instagram/
261
- ├── creds.json # Authorization tokens (Bearer token, claims)
262
- ├── device.json # Device information (device ID, UUID, phone ID)
263
- ├── cookies.json # HTTP cookies for API requests
264
- ├── mqtt-session.json # MQTT real-time session data
265
- ├── subscriptions.json # GraphQL and Skywalker subscriptions
266
- ├── seq-ids.json # Sequence IDs for message sync
267
- └── app-state.json # Application state and preferences
268
- ```
269
302
 
270
- ### Basic Usage
303
+ ### 🔐 Initial Setup (Pairing)
304
+
305
+ The first time you run your bot, you need to perform a "pairing" login to generate the session files.
271
306
 
272
307
  ```javascript
273
308
  const { IgApiClient, RealtimeClient, useMultiFileAuthState } = require('nodejs-insta-private-api-mqtt');
274
309
 
275
- async function main() {
276
- // Initialize multi-file auth state
277
- const authState = await useMultiFileAuthState('./auth_info_instagram');
278
-
279
- const ig = new IgApiClient();
310
+ async function pair() {
311
+ const ig = new IgApiClient();
312
+ const folder = './auth_info_ig'; // Default folder for instant boot
313
+ const auth = await useMultiFileAuthState(folder);
314
+ const realtime = new RealtimeClient(ig);
280
315
 
281
- // Check if we have a saved session
282
- if (authState.hasSession()) {
283
- console.log('Loading saved session...');
284
-
285
- // Load credentials from files
286
- await authState.loadCreds(ig);
287
-
288
- // Validate session with Instagram
289
- const isValid = await authState.isSessionValid(ig);
290
-
291
- if (isValid) {
292
- console.log('Session valid! Connecting to MQTT...');
293
-
294
- // Connect using saved MQTT session
295
- const realtime = new RealtimeClient(ig);
296
- await realtime.connectFromSavedSession(authState);
297
-
298
- realtime.on('message', (data) => {
299
- console.log('New DM:', data.message.text);
300
- });
301
-
302
- console.log('Bot is running!');
303
- } else {
304
- console.log('Session expired, need fresh login');
305
- await freshLogin(ig, authState);
316
+ if (!auth.hasSession()) {
317
+ console.log('Linking account...');
318
+ await ig.state.generateDevice('your_username');
319
+ await ig.login({ username: 'your_username', password: 'your_password' });
320
+
321
+ // Save credentials
322
+ await auth.saveCreds(ig);
323
+
324
+ // Fetch initial sync data and connect MQTT
325
+ await realtime.startRealTimeListener();
326
+
327
+ // Save the MQTT session for instant boot next time
328
+ await auth.saveMqttSession(realtime);
329
+
330
+ console.log('✅ Pairing complete! Restart your script to see Instant Boot in action.');
306
331
  }
307
- } else {
308
- console.log('No session found, logging in...');
309
- await freshLogin(ig, authState);
310
- }
311
332
  }
312
333
 
313
- async function freshLogin(ig, authState) {
314
- // Login with credentials
315
- await ig.login({
316
- username: 'your_username',
317
- password: 'your_password'
318
- });
319
-
320
- // Save credentials to files
321
- await authState.saveCreds(ig);
322
- console.log('Credentials saved!');
323
-
324
- // Connect to MQTT
325
- const realtime = new RealtimeClient(ig);
326
- const inbox = await ig.direct.getInbox();
327
-
328
- await realtime.connect({
329
- graphQlSubs: ['ig_sub_direct', 'ig_sub_direct_v2_message_sync'],
330
- skywalkerSubs: ['presence_subscribe', 'typing_subscribe'],
331
- irisData: inbox
332
- });
333
-
334
- // Save MQTT session
335
- await authState.saveMqttSession(realtime);
336
- console.log('MQTT session saved!');
337
-
338
- realtime.on('message', (data) => {
339
- console.log('New DM:', data.message.text);
340
- });
341
- }
334
+ pair().catch(console.error);
335
+ ```
336
+
337
+
338
+ ### 🔄 Comparison: Old vs New MQTT Logic
339
+
340
+ | Feature | **BEFORE (Manual)** | **NOW (Instant)** |
341
+ |:--- |:--- |:--- |
342
+ | **Setup** | Manual login + inbox fetch | Just initialize the client |
343
+ | **MQTT Startup** | Manual `realtime.connect()` | Starts automatically in background |
344
+ | **IRIS Sub** | Must pass `irisData` manually | Auto-fetches and connects |
345
+ | **Session** | You manage cookie serialization | Handled by `useMultiFileAuthState` |
346
+
347
+ #### The Old Way (Painful 😫)
348
+ ```javascript
349
+ const ig = new IgApiClient();
350
+ await ig.login({ username: '...', password: '...' });
351
+ const inbox = await ig.direct.getInbox(); // Manual step
352
+
353
+ const realtime = new RealtimeClient(ig);
354
+ await realtime.connect({
355
+ graphQlSubs: ['ig_sub_direct'],
356
+ irisData: inbox // Manual injection
357
+ });
358
+ ```
359
+
360
+ #### The New Way (Instant 🚀)
361
+ ```javascript
362
+ const ig = new IgApiClient();
363
+ // If ./auth_info_ig exists, this line starts the background connection!
364
+ const realtime = new RealtimeClient(ig);
342
365
 
343
- main();
366
+ realtime.on('connected', () => console.log('✅ Online!'));
344
367
  ```
345
368
 
346
- ### API Reference: useMultiFileAuthState
347
369
 
348
370
  ```javascript
349
371
  const authState = await useMultiFileAuthState(folderPath);
@@ -46,6 +46,26 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
46
46
 
47
47
  this.realtimeDebug(`Applying mixins: ${mixins.map(m => m.name).join(', ')}`);
48
48
  (0, mixins_1.applyMixins)(mixins, this, this.ig);
49
+
50
+ // Auto-connect if session is available
51
+ const folder = './auth_info_ig';
52
+ const { useMultiFileAuthState } = require('../useMultiFileAuthState');
53
+ const fs = require('fs');
54
+ const path = require('path');
55
+ if (fs.existsSync(path.join(folder, 'creds.json'))) {
56
+ setTimeout(async () => {
57
+ try {
58
+ const auth = await useMultiFileAuthState(folder);
59
+ if (auth.hasSession()) {
60
+ console.log('[REALTIME] Auto-starting MQTT from constructor...');
61
+ await auth.loadCreds(this.ig);
62
+ await this.connectFromSavedSession(auth);
63
+ }
64
+ } catch (e) {
65
+ console.error('[REALTIME] Constructor auto-connect failed:', e.message);
66
+ }
67
+ }, 100);
68
+ }
49
69
  }
50
70
 
51
71
  /**