nodejs-insta-private-api-mqtt 1.0.0
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 +1650 -0
- package/dist/constants/constants.js +280 -0
- package/dist/constants/index.js +41 -0
- package/dist/core/client.js +243 -0
- package/dist/core/repository.js +7 -0
- package/dist/core/request.js +212 -0
- package/dist/core/state.js +1456 -0
- package/dist/core/utils.js +786 -0
- package/dist/downloadMedia.js +381 -0
- package/dist/errors/index.d.ts +16 -0
- package/dist/errors/index.js +30 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/fbns/fbns.client.d.ts +32 -0
- package/dist/fbns/fbns.client.events.d.ts +41 -0
- package/dist/fbns/fbns.client.events.js +3 -0
- package/dist/fbns/fbns.client.events.js.map +1 -0
- package/dist/fbns/fbns.client.js +179 -0
- package/dist/fbns/fbns.client.js.map +1 -0
- package/dist/fbns/fbns.device-auth.d.ts +17 -0
- package/dist/fbns/fbns.device-auth.js +54 -0
- package/dist/fbns/fbns.device-auth.js.map +1 -0
- package/dist/fbns/fbns.types.d.ts +83 -0
- package/dist/fbns/fbns.types.js +3 -0
- package/dist/fbns/fbns.types.js.map +1 -0
- package/dist/fbns/fbns.utilities.d.ts +2 -0
- package/dist/fbns/fbns.utilities.js +79 -0
- package/dist/fbns/fbns.utilities.js.map +1 -0
- package/dist/fbns/index.d.ts +4 -0
- package/dist/fbns/index.js +21 -0
- package/dist/fbns/index.js.map +1 -0
- package/dist/index.js +39 -0
- package/dist/mqttot/index.d.ts +4 -0
- package/dist/mqttot/index.js +21 -0
- package/dist/mqttot/index.js.map +1 -0
- package/dist/mqttot/mqttot.client.d.ts +39 -0
- package/dist/mqttot/mqttot.client.js +120 -0
- package/dist/mqttot/mqttot.client.js.map +1 -0
- package/dist/mqttot/mqttot.connect.request.packet.d.ts +7 -0
- package/dist/mqttot/mqttot.connect.request.packet.js +9 -0
- package/dist/mqttot/mqttot.connect.request.packet.js.map +1 -0
- package/dist/mqttot/mqttot.connect.response.packet.d.ts +7 -0
- package/dist/mqttot/mqttot.connect.response.packet.js +24 -0
- package/dist/mqttot/mqttot.connect.response.packet.js.map +1 -0
- package/dist/mqttot/mqttot.connection.d.ts +57 -0
- package/dist/mqttot/mqttot.connection.js +56 -0
- package/dist/mqttot/mqttot.connection.js.map +1 -0
- package/dist/package.json +59 -0
- package/dist/realtime/commands/commands.d.ts +15 -0
- package/dist/realtime/commands/commands.js +21 -0
- package/dist/realtime/commands/commands.js.map +1 -0
- package/dist/realtime/commands/direct.commands.d.ts +75 -0
- package/dist/realtime/commands/direct.commands.js +186 -0
- package/dist/realtime/commands/direct.commands.js.map +1 -0
- package/dist/realtime/commands/enhanced.direct.commands.js +987 -0
- package/dist/realtime/commands/index.d.ts +2 -0
- package/dist/realtime/commands/index.js +19 -0
- package/dist/realtime/commands/index.js.map +1 -0
- package/dist/realtime/delta-sync.manager.js +293 -0
- package/dist/realtime/features/dm-sender.js +88 -0
- package/dist/realtime/features/error-handler.js +73 -0
- package/dist/realtime/features/gap-handler.js +61 -0
- package/dist/realtime/features/presence.manager.js +66 -0
- package/dist/realtime/index.js +30 -0
- package/dist/realtime/messages/app-presence.event.d.ts +9 -0
- package/dist/realtime/messages/app-presence.event.js +3 -0
- package/dist/realtime/messages/app-presence.event.js.map +1 -0
- package/dist/realtime/messages/index.d.ts +3 -0
- package/dist/realtime/messages/index.js +20 -0
- package/dist/realtime/messages/index.js.map +1 -0
- package/dist/realtime/messages/message-sync.message.d.ts +222 -0
- package/dist/realtime/messages/message-sync.message.js +43 -0
- package/dist/realtime/messages/message-sync.message.js.map +1 -0
- package/dist/realtime/messages/realtime-sub.direct.data.d.ts +11 -0
- package/dist/realtime/messages/realtime-sub.direct.data.js +3 -0
- package/dist/realtime/messages/realtime-sub.direct.data.js.map +1 -0
- package/dist/realtime/messages/thread-update.message.d.ts +68 -0
- package/dist/realtime/messages/thread-update.message.js +3 -0
- package/dist/realtime/messages/thread-update.message.js.map +1 -0
- package/dist/realtime/mixins/index.d.ts +3 -0
- package/dist/realtime/mixins/index.js +20 -0
- package/dist/realtime/mixins/index.js.map +1 -0
- package/dist/realtime/mixins/message-sync.mixin.d.ts +8 -0
- package/dist/realtime/mixins/message-sync.mixin.js +381 -0
- package/dist/realtime/mixins/message-sync.mixin.js.map +1 -0
- package/dist/realtime/mixins/mixin.d.ts +19 -0
- package/dist/realtime/mixins/mixin.js +41 -0
- package/dist/realtime/mixins/mixin.js.map +1 -0
- package/dist/realtime/mixins/presence-typing.mixin.js +33 -0
- package/dist/realtime/mixins/realtime-sub.mixin.d.ts +8 -0
- package/dist/realtime/mixins/realtime-sub.mixin.js +55 -0
- package/dist/realtime/mixins/realtime-sub.mixin.js.map +1 -0
- package/dist/realtime/parsers/graphql-parser.js +43 -0
- package/dist/realtime/parsers/graphql.parser.d.ts +15 -0
- package/dist/realtime/parsers/graphql.parser.js +22 -0
- package/dist/realtime/parsers/graphql.parser.js.map +1 -0
- package/dist/realtime/parsers/index.d.ts +6 -0
- package/dist/realtime/parsers/index.js +23 -0
- package/dist/realtime/parsers/index.js.map +1 -0
- package/dist/realtime/parsers/iris-parser.js +43 -0
- package/dist/realtime/parsers/iris.parser.d.ts +17 -0
- package/dist/realtime/parsers/iris.parser.js +10 -0
- package/dist/realtime/parsers/iris.parser.js.map +1 -0
- package/dist/realtime/parsers/json-parser.js +43 -0
- package/dist/realtime/parsers/json.parser.d.ts +6 -0
- package/dist/realtime/parsers/json.parser.js +10 -0
- package/dist/realtime/parsers/json.parser.js.map +1 -0
- package/dist/realtime/parsers/parser.d.ts +9 -0
- package/dist/realtime/parsers/parser.js +3 -0
- package/dist/realtime/parsers/parser.js.map +1 -0
- package/dist/realtime/parsers/region-hint-parser.js +43 -0
- package/dist/realtime/parsers/region-hint.parser.d.ts +12 -0
- package/dist/realtime/parsers/region-hint.parser.js +15 -0
- package/dist/realtime/parsers/region-hint.parser.js.map +1 -0
- package/dist/realtime/parsers/skywalker-parser.js +43 -0
- package/dist/realtime/parsers/skywalker.parser.d.ts +12 -0
- package/dist/realtime/parsers/skywalker.parser.js +15 -0
- package/dist/realtime/parsers/skywalker.parser.js.map +1 -0
- package/dist/realtime/parsers-advanced.js +158 -0
- package/dist/realtime/proto/common.proto +38 -0
- package/dist/realtime/proto/direct.proto +65 -0
- package/dist/realtime/proto/ig-messages.proto +83 -0
- package/dist/realtime/proto/iris.proto +188 -0
- package/dist/realtime/proto-parser.js +195 -0
- package/dist/realtime/protocols/iris.handshake.js +74 -0
- package/dist/realtime/protocols/proto-definitions.js +80 -0
- package/dist/realtime/protocols/skywalker.protocol.js +91 -0
- package/dist/realtime/realtime.client.events.js +3 -0
- package/dist/realtime/realtime.client.js +449 -0
- package/dist/realtime/realtime.service.js +462 -0
- package/dist/realtime/reconnect.manager.js +94 -0
- package/dist/realtime/session.manager.js +121 -0
- package/dist/realtime/subscriptions/graphql.subscription.d.ts +47 -0
- package/dist/realtime/subscriptions/graphql.subscription.js +99 -0
- package/dist/realtime/subscriptions/graphql.subscription.js.map +1 -0
- package/dist/realtime/subscriptions/index.d.ts +2 -0
- package/dist/realtime/subscriptions/index.js +19 -0
- package/dist/realtime/subscriptions/index.js.map +1 -0
- package/dist/realtime/subscriptions/skywalker.subscription.d.ts +4 -0
- package/dist/realtime/subscriptions/skywalker.subscription.js +13 -0
- package/dist/realtime/subscriptions/skywalker.subscription.js.map +1 -0
- package/dist/realtime/topic-map.js +71 -0
- package/dist/realtime/topic.js +80 -0
- package/dist/repositories/account.repository.js +261 -0
- package/dist/repositories/direct-thread.repository.js +247 -0
- package/dist/repositories/direct.repository.js +153 -0
- package/dist/repositories/feed.repository.js +233 -0
- package/dist/repositories/friendship.repository.js +190 -0
- package/dist/repositories/hashtag.repository.js +101 -0
- package/dist/repositories/highlights.repository.js +127 -0
- package/dist/repositories/location.repository.js +84 -0
- package/dist/repositories/media.repository.js +165 -0
- package/dist/repositories/story.repository.js +156 -0
- package/dist/repositories/upload.repository.js +167 -0
- package/dist/repositories/user.repository.js +94 -0
- package/dist/sendmedia/index.js +11 -0
- package/dist/sendmedia/sendFile.js +154 -0
- package/dist/sendmedia/sendPhoto.js +145 -0
- package/dist/sendmedia/uploadPhoto.js +175 -0
- package/dist/sendmedia/uploadfFile.js +264 -0
- package/dist/services/live.service.js +147 -0
- package/dist/services/search.service.js +116 -0
- package/dist/shared/index.js +35 -0
- package/dist/shared/shared.js +86 -0
- package/dist/thrift/index.d.ts +3 -0
- package/dist/thrift/index.js +20 -0
- package/dist/thrift/index.js.map +1 -0
- package/dist/thrift/thrift.d.ts +59 -0
- package/dist/thrift/thrift.js +101 -0
- package/dist/thrift/thrift.js.map +1 -0
- package/dist/thrift/thrift.reading.d.ts +41 -0
- package/dist/thrift/thrift.reading.js +327 -0
- package/dist/thrift/thrift.reading.js.map +1 -0
- package/dist/thrift/thrift.writing.d.ts +44 -0
- package/dist/thrift/thrift.writing.js +342 -0
- package/dist/thrift/thrift.writing.js.map +1 -0
- package/dist/types/index.js +285 -0
- package/dist/useMultiFileAuthState.js +437 -0
- package/dist/utils/helper-1.js +1 -0
- package/dist/utils/helper-10.js +1 -0
- package/dist/utils/helper-11.js +1 -0
- package/dist/utils/helper-12.js +1 -0
- package/dist/utils/helper-13.js +1 -0
- package/dist/utils/helper-14.js +1 -0
- package/dist/utils/helper-15.js +1 -0
- package/dist/utils/helper-16.js +1 -0
- package/dist/utils/helper-17.js +1 -0
- package/dist/utils/helper-18.js +1 -0
- package/dist/utils/helper-19.js +1 -0
- package/dist/utils/helper-2.js +1 -0
- package/dist/utils/helper-20.js +1 -0
- package/dist/utils/helper-21.js +1 -0
- package/dist/utils/helper-22.js +1 -0
- package/dist/utils/helper-23.js +1 -0
- package/dist/utils/helper-24.js +1 -0
- package/dist/utils/helper-25.js +1 -0
- package/dist/utils/helper-26.js +1 -0
- package/dist/utils/helper-27.js +1 -0
- package/dist/utils/helper-28.js +1 -0
- package/dist/utils/helper-29.js +1 -0
- package/dist/utils/helper-3.js +1 -0
- package/dist/utils/helper-30.js +1 -0
- package/dist/utils/helper-4.js +1 -0
- package/dist/utils/helper-5.js +1 -0
- package/dist/utils/helper-6.js +1 -0
- package/dist/utils/helper-7.js +1 -0
- package/dist/utils/helper-8.js +1 -0
- package/dist/utils/helper-9.js +1 -0
- package/dist/utils/index.js +280 -0
- package/examples/listen-to-messages.js +86 -0
- package/package.json +79 -0
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RealtimeClient = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
const commands_1 = require("./commands");
|
|
6
|
+
const shared_1 = require("../shared");
|
|
7
|
+
const mqttot_1 = require("../mqttot");
|
|
8
|
+
const mqtts_1 = require("mqtts");
|
|
9
|
+
const errors_1 = require("../errors");
|
|
10
|
+
const eventemitter3_1 = require("eventemitter3");
|
|
11
|
+
const mixins_1 = require("./mixins");
|
|
12
|
+
const iris_handshake_1 = require("./protocols/iris.handshake");
|
|
13
|
+
const skywalker_protocol_1 = require("./protocols/skywalker.protocol");
|
|
14
|
+
const presence_manager_1 = require("./features/presence.manager");
|
|
15
|
+
const dm_sender_1 = require("./features/dm-sender");
|
|
16
|
+
const error_handler_1 = require("./features/error-handler");
|
|
17
|
+
const gap_handler_1 = require("./features/gap-handler");
|
|
18
|
+
const enhanced_direct_commands_1 = require("./commands/enhanced.direct.commands");
|
|
19
|
+
const presence_typing_mixin_1 = require("./mixins/presence-typing.mixin");
|
|
20
|
+
class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
21
|
+
get mqtt() {
|
|
22
|
+
return this._mqtt;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @param {IgApiClient} ig
|
|
27
|
+
* @param mixins - by default MessageSync and Realtime mixins are used
|
|
28
|
+
*/
|
|
29
|
+
constructor(ig, mixins = [new mixins_1.MessageSyncMixin(), new mixins_1.RealtimeSubMixin(), new presence_typing_mixin_1.PresenceTypingMixin()]) {
|
|
30
|
+
super();
|
|
31
|
+
this.realtimeDebug = (0, shared_1.debugChannel)('realtime');
|
|
32
|
+
this.messageDebug = this.realtimeDebug.extend('message');
|
|
33
|
+
this.safeDisconnect = false;
|
|
34
|
+
this.emitError = (e) => this.emit('error', e);
|
|
35
|
+
this.emitWarning = (e) => this.emit('warning', e);
|
|
36
|
+
this.ig = ig;
|
|
37
|
+
this.threads = new Map();
|
|
38
|
+
|
|
39
|
+
this.irisHandshake = new iris_handshake_1.IrisHandshake(this);
|
|
40
|
+
this.skywalkerProtocol = new skywalker_protocol_1.SkywalkerProtocol(this);
|
|
41
|
+
this.presenceManager = new presence_manager_1.PresenceManager(this);
|
|
42
|
+
this.dmSender = new dm_sender_1.DMSender(this);
|
|
43
|
+
this.errorHandler = new error_handler_1.ErrorHandler(this);
|
|
44
|
+
this.gapHandler = new gap_handler_1.GapHandler(this);
|
|
45
|
+
this.directCommands = new enhanced_direct_commands_1.EnhancedDirectCommands(this);
|
|
46
|
+
|
|
47
|
+
this.realtimeDebug(`Applying mixins: ${mixins.map(m => m.name).join(', ')}`);
|
|
48
|
+
(0, mixins_1.applyMixins)(mixins, this, this.ig);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Start Real-Time Listener with Auto-Inbox Fetch + MQTT
|
|
53
|
+
*/
|
|
54
|
+
async startRealTimeListener(options = {}) {
|
|
55
|
+
try {
|
|
56
|
+
console.log('[REALTIME] Starting Real-Time Listener...');
|
|
57
|
+
|
|
58
|
+
console.log('[REALTIME] Fetching inbox (IRIS data)...');
|
|
59
|
+
const inboxData = await this.ig.direct.getInbox();
|
|
60
|
+
|
|
61
|
+
console.log('[REALTIME] Connecting to MQTT with IRIS subscription...');
|
|
62
|
+
await this.connect({
|
|
63
|
+
graphQlSubs: [
|
|
64
|
+
'ig_sub_direct',
|
|
65
|
+
'ig_sub_direct_v2_message_create',
|
|
66
|
+
],
|
|
67
|
+
skywalkerSubs: [
|
|
68
|
+
'presence_subscribe',
|
|
69
|
+
'typing_subscribe',
|
|
70
|
+
],
|
|
71
|
+
irisData: inboxData
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
console.log('[REALTIME] MQTT Connected with IRIS');
|
|
75
|
+
console.log('----------------------------------------');
|
|
76
|
+
console.log('[REALTIME] Real-Time Listener ACTIVE');
|
|
77
|
+
console.log('[REALTIME] Waiting for messages...');
|
|
78
|
+
console.log('----------------------------------------');
|
|
79
|
+
|
|
80
|
+
this._setupMessageHandlers();
|
|
81
|
+
|
|
82
|
+
return { success: true };
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error('[REALTIME] Failed:', error.message);
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Setup automatic message handlers
|
|
91
|
+
*/
|
|
92
|
+
_setupMessageHandlers() {
|
|
93
|
+
this.on('message', (data) => {
|
|
94
|
+
const msg = this._parseMessage(data);
|
|
95
|
+
if (msg) {
|
|
96
|
+
this.emit('message_live', msg);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
this.on('iris', (data) => {
|
|
101
|
+
const msg = this._parseIrisMessage(data);
|
|
102
|
+
if (msg) {
|
|
103
|
+
this.emit('message_live', msg);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Parse direct message
|
|
110
|
+
*/
|
|
111
|
+
_parseMessage(data) {
|
|
112
|
+
try {
|
|
113
|
+
const msg = data.message;
|
|
114
|
+
if (!msg) return null;
|
|
115
|
+
|
|
116
|
+
if (data.parsed) {
|
|
117
|
+
return data.parsed;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const threadInfo = this.threads.get(msg.thread_id);
|
|
121
|
+
return {
|
|
122
|
+
id: msg.item_id || msg.id,
|
|
123
|
+
userId: msg.user_id || msg.from_user_id,
|
|
124
|
+
username: msg.username || msg.from_username || `user_${msg.user_id || 'unknown'}`,
|
|
125
|
+
text: msg.text || msg.body || '',
|
|
126
|
+
itemType: msg.item_type || 'text',
|
|
127
|
+
thread: threadInfo?.title || `Thread ${msg.thread_id}`,
|
|
128
|
+
thread_id: msg.thread_id,
|
|
129
|
+
timestamp: msg.timestamp,
|
|
130
|
+
isGroup: threadInfo?.isGroup,
|
|
131
|
+
status: 'good'
|
|
132
|
+
};
|
|
133
|
+
} catch (e) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Parse iris message
|
|
140
|
+
*/
|
|
141
|
+
_parseIrisMessage(data) {
|
|
142
|
+
try {
|
|
143
|
+
if (data.event !== 'message_create' && !data.type?.includes('message')) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
id: data.item_id || data.id,
|
|
149
|
+
userId: data.user_id || data.from_user_id,
|
|
150
|
+
username: data.username || data.from_username || `user_${data.user_id || 'unknown'}`,
|
|
151
|
+
text: data.text || '',
|
|
152
|
+
itemType: data.item_type || 'text',
|
|
153
|
+
thread_id: data.thread_id,
|
|
154
|
+
timestamp: data.timestamp,
|
|
155
|
+
status: 'good'
|
|
156
|
+
};
|
|
157
|
+
} catch (e) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
setInitOptions(initOptions) {
|
|
163
|
+
if (Array.isArray(initOptions))
|
|
164
|
+
initOptions = { graphQlSubs: initOptions };
|
|
165
|
+
this.initOptions = {
|
|
166
|
+
graphQlSubs: [],
|
|
167
|
+
skywalkerSubs: [],
|
|
168
|
+
...(initOptions || {}),
|
|
169
|
+
socksOptions: typeof initOptions === 'object' && !Array.isArray(initOptions) ? initOptions.socksOptions : undefined,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
extractSessionIdFromJWT() {
|
|
173
|
+
try {
|
|
174
|
+
const authHeader = this.ig.state.authorization;
|
|
175
|
+
if (!authHeader) return null;
|
|
176
|
+
// Extract base64 part from "Bearer IGT:2:{base64}"
|
|
177
|
+
const base64Part = authHeader.replace('Bearer IGT:2:', '').replace('Bearer ', '');
|
|
178
|
+
// Decode from base64
|
|
179
|
+
const decoded = Buffer.from(base64Part, 'base64').toString();
|
|
180
|
+
const payload = JSON.parse(decoded);
|
|
181
|
+
// Get sessionid and URL-decode it
|
|
182
|
+
let sessionid = payload.sessionid;
|
|
183
|
+
if (sessionid) {
|
|
184
|
+
sessionid = decodeURIComponent(sessionid);
|
|
185
|
+
}
|
|
186
|
+
return sessionid || null;
|
|
187
|
+
} catch (e) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
constructConnection() {
|
|
192
|
+
const userAgent = this.ig.state.appUserAgent;
|
|
193
|
+
const deviceId = this.ig.state.phoneId;
|
|
194
|
+
let sessionid;
|
|
195
|
+
// First try: Extract from JWT authorization header (PRIMARY METHOD)
|
|
196
|
+
sessionid = this.extractSessionIdFromJWT();
|
|
197
|
+
if (sessionid) {
|
|
198
|
+
this.realtimeDebug(`SessionID extracted from JWT: ${sessionid.substring(0, 20)}...`);
|
|
199
|
+
}
|
|
200
|
+
// Second try: Direct cookie lookup
|
|
201
|
+
if (!sessionid) {
|
|
202
|
+
try {
|
|
203
|
+
sessionid = this.ig.state.extractCookieValue('sessionid');
|
|
204
|
+
} catch (e) {
|
|
205
|
+
sessionid = null;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Third try: Parsed authorization
|
|
209
|
+
if (!sessionid) {
|
|
210
|
+
try {
|
|
211
|
+
sessionid = this.ig.state.parsedAuthorization?.sessionid;
|
|
212
|
+
} catch (e2) {
|
|
213
|
+
sessionid = null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Fourth try: CookieJar introspection
|
|
217
|
+
if (!sessionid) {
|
|
218
|
+
try {
|
|
219
|
+
const cookies = this.ig.state.cookieJar.getCookiesSync('https://i.instagram.com/');
|
|
220
|
+
const sessionCookie = cookies.find(c => c.key === 'sessionid');
|
|
221
|
+
sessionid = sessionCookie?.value;
|
|
222
|
+
} catch (e) {
|
|
223
|
+
sessionid = null;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Last resort: Generate from userId + timestamp
|
|
227
|
+
if (!sessionid) {
|
|
228
|
+
const userId = this.ig.state.cookieUserId;
|
|
229
|
+
sessionid = userId + '_' + Date.now();
|
|
230
|
+
this.realtimeDebug(`SessionID generated (fallback): ${sessionid}`);
|
|
231
|
+
}
|
|
232
|
+
const password = `sessionid=${sessionid}`;
|
|
233
|
+
this.connection = new mqttot_1.MQTToTConnection({
|
|
234
|
+
clientIdentifier: deviceId.substring(0, 20),
|
|
235
|
+
clientInfo: {
|
|
236
|
+
userId: BigInt(Number(this.ig.state.cookieUserId)),
|
|
237
|
+
userAgent,
|
|
238
|
+
clientCapabilities: 183,
|
|
239
|
+
endpointCapabilities: 0,
|
|
240
|
+
publishFormat: 1,
|
|
241
|
+
noAutomaticForeground: false,
|
|
242
|
+
makeUserAvailableInForeground: true,
|
|
243
|
+
deviceId,
|
|
244
|
+
isInitiallyForeground: true,
|
|
245
|
+
networkType: 1,
|
|
246
|
+
networkSubtype: 0,
|
|
247
|
+
clientMqttSessionId: BigInt(Date.now()) & BigInt(0xffffffff),
|
|
248
|
+
subscribeTopics: [88, 135, 149, 150, 133, 146],
|
|
249
|
+
clientType: 'cookie_auth',
|
|
250
|
+
appId: BigInt(567067343352427),
|
|
251
|
+
deviceSecret: '',
|
|
252
|
+
clientStack: 3,
|
|
253
|
+
...(this.initOptions?.connectOverrides || {}),
|
|
254
|
+
},
|
|
255
|
+
password,
|
|
256
|
+
appSpecificInfo: {
|
|
257
|
+
app_version: this.ig.state.appVersion,
|
|
258
|
+
'X-IG-Capabilities': this.ig.state.capabilitiesHeader,
|
|
259
|
+
everclear_subscriptions: JSON.stringify({
|
|
260
|
+
inapp_notification_subscribe_comment: '17899377895239777',
|
|
261
|
+
inapp_notification_subscribe_comment_mention_and_reply: '17899377895239777',
|
|
262
|
+
video_call_participant_state_delivery: '17977239895057311',
|
|
263
|
+
presence_subscribe: '17846944882223835',
|
|
264
|
+
}),
|
|
265
|
+
'User-Agent': userAgent,
|
|
266
|
+
'Accept-Language': this.ig.state.language.replace('_', '-'),
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
async connect(options) {
|
|
271
|
+
this.setInitOptions(options);
|
|
272
|
+
this.constructConnection();
|
|
273
|
+
const { MQTToTClient } = require("../mqttot");
|
|
274
|
+
const { compressDeflate } = require("../shared");
|
|
275
|
+
|
|
276
|
+
this._mqtt = new MQTToTClient({
|
|
277
|
+
url: 'edge-mqtt.facebook.com',
|
|
278
|
+
payloadProvider: async () => {
|
|
279
|
+
return await compressDeflate(this.connection.toThrift());
|
|
280
|
+
},
|
|
281
|
+
autoReconnect: true,
|
|
282
|
+
requirePayload: true,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
await this._mqtt.connect();
|
|
286
|
+
|
|
287
|
+
this.commands = new commands_1.Commands(this._mqtt);
|
|
288
|
+
|
|
289
|
+
this.emit('connected');
|
|
290
|
+
|
|
291
|
+
this._mqtt.on('message', async (msg) => {
|
|
292
|
+
const topicMap = this.mqtt?.topicMap;
|
|
293
|
+
const topic = topicMap?.get(msg.topic);
|
|
294
|
+
|
|
295
|
+
if (topic && topic.parser && !topic.noParse) {
|
|
296
|
+
try {
|
|
297
|
+
const unzipped = await (0, shared_1.tryUnzipAsync)(msg.payload);
|
|
298
|
+
const parsedMessages = topic.parser.parseMessage(topic, unzipped);
|
|
299
|
+
this.emit('receive', topic, Array.isArray(parsedMessages) ? parsedMessages : [parsedMessages]);
|
|
300
|
+
} catch(e) {
|
|
301
|
+
// Silent parse error
|
|
302
|
+
}
|
|
303
|
+
} else {
|
|
304
|
+
try {
|
|
305
|
+
await (0, shared_1.tryUnzipAsync)(msg.payload);
|
|
306
|
+
this.emit('receiveRaw', msg);
|
|
307
|
+
} catch(e) {
|
|
308
|
+
// Silent decompress error
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
this._mqtt.on('error', this.emitError);
|
|
313
|
+
await (0, shared_1.delay)(100);
|
|
314
|
+
if (this.initOptions.graphQlSubs && this.initOptions.graphQlSubs.length > 0) {
|
|
315
|
+
await this.graphQlSubscribe(this.initOptions.graphQlSubs);
|
|
316
|
+
}
|
|
317
|
+
if (this.initOptions.irisData) {
|
|
318
|
+
await this.irisSubscribe(this.initOptions.irisData);
|
|
319
|
+
} else {
|
|
320
|
+
// Auto-fetch irisData if not provided
|
|
321
|
+
try {
|
|
322
|
+
console.log('[REALTIME] Auto-fetching IRIS data...');
|
|
323
|
+
const autoIrisData = await this.ig.direct.getInbox();
|
|
324
|
+
if (autoIrisData) {
|
|
325
|
+
await this.irisSubscribe(autoIrisData);
|
|
326
|
+
console.log('[REALTIME] IRIS subscription successful');
|
|
327
|
+
}
|
|
328
|
+
} catch (e) {
|
|
329
|
+
console.log('[REALTIME] Could not auto-fetch IRIS data:', e.message);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if ((this.initOptions.skywalkerSubs ?? []).length > 0) {
|
|
333
|
+
await this.skywalkerSubscribe(this.initOptions.skywalkerSubs);
|
|
334
|
+
}
|
|
335
|
+
await (0, shared_1.delay)(100);
|
|
336
|
+
try {
|
|
337
|
+
await this.ig.direct.getInbox();
|
|
338
|
+
try {
|
|
339
|
+
await this.ig.request.send({
|
|
340
|
+
url: '/api/v1/direct_v2/threads/get_most_recent_message/',
|
|
341
|
+
method: 'POST',
|
|
342
|
+
});
|
|
343
|
+
} catch(e) {
|
|
344
|
+
// Silent force fetch error
|
|
345
|
+
}
|
|
346
|
+
} catch (error) {
|
|
347
|
+
// Silent inbox fetch error - MQTT still listening
|
|
348
|
+
}
|
|
349
|
+
this._setupMessageHandlers();
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Connect from saved session using MultiFileAuthState
|
|
353
|
+
* @param {Object} authStateHelper - Result from useMultiFileAuthState()
|
|
354
|
+
* @param {Object} options - Additional connect options
|
|
355
|
+
*/
|
|
356
|
+
async connectFromSavedSession(authStateHelper, options = {}) {
|
|
357
|
+
if (!authStateHelper) {
|
|
358
|
+
throw new Error('authStateHelper is required - use useMultiFileAuthState()');
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
console.log('[RealtimeClient] Connecting from saved session...');
|
|
362
|
+
|
|
363
|
+
const savedOptions = authStateHelper.getMqttConnectOptions?.();
|
|
364
|
+
|
|
365
|
+
const connectOptions = {
|
|
366
|
+
graphQlSubs: options.graphQlSubs || savedOptions?.graphQlSubs || ['ig_sub_direct', 'ig_sub_direct_v2_message_sync'],
|
|
367
|
+
skywalkerSubs: options.skywalkerSubs || savedOptions?.skywalkerSubs || ['presence_subscribe', 'typing_subscribe'],
|
|
368
|
+
irisData: options.irisData || savedOptions?.irisData || null,
|
|
369
|
+
...options
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
console.log('[RealtimeClient] Using saved subscriptions:', {
|
|
373
|
+
graphQlSubs: connectOptions.graphQlSubs,
|
|
374
|
+
skywalkerSubs: connectOptions.skywalkerSubs,
|
|
375
|
+
hasIrisData: !!connectOptions.irisData
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
await this.connect(connectOptions);
|
|
379
|
+
|
|
380
|
+
if (authStateHelper.saveMqttSession) {
|
|
381
|
+
try {
|
|
382
|
+
await authStateHelper.saveMqttSession(this);
|
|
383
|
+
console.log('[RealtimeClient] MQTT session saved after connect');
|
|
384
|
+
} catch (e) {
|
|
385
|
+
console.warn('[RealtimeClient] Failed to save MQTT session:', e.message);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return this;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Save current MQTT session state
|
|
393
|
+
* @param {Object} authStateHelper - Result from useMultiFileAuthState()
|
|
394
|
+
*/
|
|
395
|
+
async saveSession(authStateHelper) {
|
|
396
|
+
if (!authStateHelper || !authStateHelper.saveMqttSession) {
|
|
397
|
+
console.warn('[RealtimeClient] No authStateHelper provided');
|
|
398
|
+
return false;
|
|
399
|
+
}
|
|
400
|
+
await authStateHelper.saveMqttSession(this);
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
disconnect() {
|
|
404
|
+
this.safeDisconnect = true;
|
|
405
|
+
return this.mqtt?.disconnect() ?? Promise.resolve();
|
|
406
|
+
}
|
|
407
|
+
graphQlSubscribe(sub) {
|
|
408
|
+
sub = typeof sub === 'string' ? [sub] : sub;
|
|
409
|
+
if (!this.commands) {
|
|
410
|
+
throw new mqtts_1.IllegalStateError('connect() must be called before graphQlSubscribe()');
|
|
411
|
+
}
|
|
412
|
+
this.realtimeDebug(`Subscribing with GraphQL to ${sub.join(', ')}`);
|
|
413
|
+
return this.commands.updateSubscriptions({
|
|
414
|
+
topic: constants_1.Topics.REALTIME_SUB,
|
|
415
|
+
data: {
|
|
416
|
+
sub,
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
skywalkerSubscribe(sub) {
|
|
421
|
+
sub = typeof sub === 'string' ? [sub] : sub;
|
|
422
|
+
if (!this.commands) {
|
|
423
|
+
throw new mqtts_1.IllegalStateError('connect() must be called before skywalkerSubscribe()');
|
|
424
|
+
}
|
|
425
|
+
this.realtimeDebug(`Subscribing with Skywalker to ${sub.join(', ')}`);
|
|
426
|
+
return this.commands.updateSubscriptions({
|
|
427
|
+
topic: constants_1.Topics.PUBSUB,
|
|
428
|
+
data: {
|
|
429
|
+
sub,
|
|
430
|
+
},
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
irisSubscribe({ seq_id, snapshot_at_ms, }) {
|
|
434
|
+
if (!this.commands) {
|
|
435
|
+
throw new mqtts_1.IllegalStateError('connect() must be called before irisSubscribe()');
|
|
436
|
+
}
|
|
437
|
+
this.realtimeDebug(`Iris Sub to: seqId: ${seq_id}, snapshot: ${snapshot_at_ms}`);
|
|
438
|
+
return this.commands.updateSubscriptions({
|
|
439
|
+
topic: constants_1.Topics.IRIS_SUB,
|
|
440
|
+
data: {
|
|
441
|
+
seq_id,
|
|
442
|
+
snapshot_at_ms,
|
|
443
|
+
snapshot_app_version: this.ig.state.appVersion,
|
|
444
|
+
},
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
exports.RealtimeClient = RealtimeClient;
|
|
449
|
+
//# sourceMappingURL=realtime.client.js.map
|