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.
Files changed (210) hide show
  1. package/README.md +1650 -0
  2. package/dist/constants/constants.js +280 -0
  3. package/dist/constants/index.js +41 -0
  4. package/dist/core/client.js +243 -0
  5. package/dist/core/repository.js +7 -0
  6. package/dist/core/request.js +212 -0
  7. package/dist/core/state.js +1456 -0
  8. package/dist/core/utils.js +786 -0
  9. package/dist/downloadMedia.js +381 -0
  10. package/dist/errors/index.d.ts +16 -0
  11. package/dist/errors/index.js +30 -0
  12. package/dist/errors/index.js.map +1 -0
  13. package/dist/fbns/fbns.client.d.ts +32 -0
  14. package/dist/fbns/fbns.client.events.d.ts +41 -0
  15. package/dist/fbns/fbns.client.events.js +3 -0
  16. package/dist/fbns/fbns.client.events.js.map +1 -0
  17. package/dist/fbns/fbns.client.js +179 -0
  18. package/dist/fbns/fbns.client.js.map +1 -0
  19. package/dist/fbns/fbns.device-auth.d.ts +17 -0
  20. package/dist/fbns/fbns.device-auth.js +54 -0
  21. package/dist/fbns/fbns.device-auth.js.map +1 -0
  22. package/dist/fbns/fbns.types.d.ts +83 -0
  23. package/dist/fbns/fbns.types.js +3 -0
  24. package/dist/fbns/fbns.types.js.map +1 -0
  25. package/dist/fbns/fbns.utilities.d.ts +2 -0
  26. package/dist/fbns/fbns.utilities.js +79 -0
  27. package/dist/fbns/fbns.utilities.js.map +1 -0
  28. package/dist/fbns/index.d.ts +4 -0
  29. package/dist/fbns/index.js +21 -0
  30. package/dist/fbns/index.js.map +1 -0
  31. package/dist/index.js +39 -0
  32. package/dist/mqttot/index.d.ts +4 -0
  33. package/dist/mqttot/index.js +21 -0
  34. package/dist/mqttot/index.js.map +1 -0
  35. package/dist/mqttot/mqttot.client.d.ts +39 -0
  36. package/dist/mqttot/mqttot.client.js +120 -0
  37. package/dist/mqttot/mqttot.client.js.map +1 -0
  38. package/dist/mqttot/mqttot.connect.request.packet.d.ts +7 -0
  39. package/dist/mqttot/mqttot.connect.request.packet.js +9 -0
  40. package/dist/mqttot/mqttot.connect.request.packet.js.map +1 -0
  41. package/dist/mqttot/mqttot.connect.response.packet.d.ts +7 -0
  42. package/dist/mqttot/mqttot.connect.response.packet.js +24 -0
  43. package/dist/mqttot/mqttot.connect.response.packet.js.map +1 -0
  44. package/dist/mqttot/mqttot.connection.d.ts +57 -0
  45. package/dist/mqttot/mqttot.connection.js +56 -0
  46. package/dist/mqttot/mqttot.connection.js.map +1 -0
  47. package/dist/package.json +59 -0
  48. package/dist/realtime/commands/commands.d.ts +15 -0
  49. package/dist/realtime/commands/commands.js +21 -0
  50. package/dist/realtime/commands/commands.js.map +1 -0
  51. package/dist/realtime/commands/direct.commands.d.ts +75 -0
  52. package/dist/realtime/commands/direct.commands.js +186 -0
  53. package/dist/realtime/commands/direct.commands.js.map +1 -0
  54. package/dist/realtime/commands/enhanced.direct.commands.js +987 -0
  55. package/dist/realtime/commands/index.d.ts +2 -0
  56. package/dist/realtime/commands/index.js +19 -0
  57. package/dist/realtime/commands/index.js.map +1 -0
  58. package/dist/realtime/delta-sync.manager.js +293 -0
  59. package/dist/realtime/features/dm-sender.js +88 -0
  60. package/dist/realtime/features/error-handler.js +73 -0
  61. package/dist/realtime/features/gap-handler.js +61 -0
  62. package/dist/realtime/features/presence.manager.js +66 -0
  63. package/dist/realtime/index.js +30 -0
  64. package/dist/realtime/messages/app-presence.event.d.ts +9 -0
  65. package/dist/realtime/messages/app-presence.event.js +3 -0
  66. package/dist/realtime/messages/app-presence.event.js.map +1 -0
  67. package/dist/realtime/messages/index.d.ts +3 -0
  68. package/dist/realtime/messages/index.js +20 -0
  69. package/dist/realtime/messages/index.js.map +1 -0
  70. package/dist/realtime/messages/message-sync.message.d.ts +222 -0
  71. package/dist/realtime/messages/message-sync.message.js +43 -0
  72. package/dist/realtime/messages/message-sync.message.js.map +1 -0
  73. package/dist/realtime/messages/realtime-sub.direct.data.d.ts +11 -0
  74. package/dist/realtime/messages/realtime-sub.direct.data.js +3 -0
  75. package/dist/realtime/messages/realtime-sub.direct.data.js.map +1 -0
  76. package/dist/realtime/messages/thread-update.message.d.ts +68 -0
  77. package/dist/realtime/messages/thread-update.message.js +3 -0
  78. package/dist/realtime/messages/thread-update.message.js.map +1 -0
  79. package/dist/realtime/mixins/index.d.ts +3 -0
  80. package/dist/realtime/mixins/index.js +20 -0
  81. package/dist/realtime/mixins/index.js.map +1 -0
  82. package/dist/realtime/mixins/message-sync.mixin.d.ts +8 -0
  83. package/dist/realtime/mixins/message-sync.mixin.js +381 -0
  84. package/dist/realtime/mixins/message-sync.mixin.js.map +1 -0
  85. package/dist/realtime/mixins/mixin.d.ts +19 -0
  86. package/dist/realtime/mixins/mixin.js +41 -0
  87. package/dist/realtime/mixins/mixin.js.map +1 -0
  88. package/dist/realtime/mixins/presence-typing.mixin.js +33 -0
  89. package/dist/realtime/mixins/realtime-sub.mixin.d.ts +8 -0
  90. package/dist/realtime/mixins/realtime-sub.mixin.js +55 -0
  91. package/dist/realtime/mixins/realtime-sub.mixin.js.map +1 -0
  92. package/dist/realtime/parsers/graphql-parser.js +43 -0
  93. package/dist/realtime/parsers/graphql.parser.d.ts +15 -0
  94. package/dist/realtime/parsers/graphql.parser.js +22 -0
  95. package/dist/realtime/parsers/graphql.parser.js.map +1 -0
  96. package/dist/realtime/parsers/index.d.ts +6 -0
  97. package/dist/realtime/parsers/index.js +23 -0
  98. package/dist/realtime/parsers/index.js.map +1 -0
  99. package/dist/realtime/parsers/iris-parser.js +43 -0
  100. package/dist/realtime/parsers/iris.parser.d.ts +17 -0
  101. package/dist/realtime/parsers/iris.parser.js +10 -0
  102. package/dist/realtime/parsers/iris.parser.js.map +1 -0
  103. package/dist/realtime/parsers/json-parser.js +43 -0
  104. package/dist/realtime/parsers/json.parser.d.ts +6 -0
  105. package/dist/realtime/parsers/json.parser.js +10 -0
  106. package/dist/realtime/parsers/json.parser.js.map +1 -0
  107. package/dist/realtime/parsers/parser.d.ts +9 -0
  108. package/dist/realtime/parsers/parser.js +3 -0
  109. package/dist/realtime/parsers/parser.js.map +1 -0
  110. package/dist/realtime/parsers/region-hint-parser.js +43 -0
  111. package/dist/realtime/parsers/region-hint.parser.d.ts +12 -0
  112. package/dist/realtime/parsers/region-hint.parser.js +15 -0
  113. package/dist/realtime/parsers/region-hint.parser.js.map +1 -0
  114. package/dist/realtime/parsers/skywalker-parser.js +43 -0
  115. package/dist/realtime/parsers/skywalker.parser.d.ts +12 -0
  116. package/dist/realtime/parsers/skywalker.parser.js +15 -0
  117. package/dist/realtime/parsers/skywalker.parser.js.map +1 -0
  118. package/dist/realtime/parsers-advanced.js +158 -0
  119. package/dist/realtime/proto/common.proto +38 -0
  120. package/dist/realtime/proto/direct.proto +65 -0
  121. package/dist/realtime/proto/ig-messages.proto +83 -0
  122. package/dist/realtime/proto/iris.proto +188 -0
  123. package/dist/realtime/proto-parser.js +195 -0
  124. package/dist/realtime/protocols/iris.handshake.js +74 -0
  125. package/dist/realtime/protocols/proto-definitions.js +80 -0
  126. package/dist/realtime/protocols/skywalker.protocol.js +91 -0
  127. package/dist/realtime/realtime.client.events.js +3 -0
  128. package/dist/realtime/realtime.client.js +449 -0
  129. package/dist/realtime/realtime.service.js +462 -0
  130. package/dist/realtime/reconnect.manager.js +94 -0
  131. package/dist/realtime/session.manager.js +121 -0
  132. package/dist/realtime/subscriptions/graphql.subscription.d.ts +47 -0
  133. package/dist/realtime/subscriptions/graphql.subscription.js +99 -0
  134. package/dist/realtime/subscriptions/graphql.subscription.js.map +1 -0
  135. package/dist/realtime/subscriptions/index.d.ts +2 -0
  136. package/dist/realtime/subscriptions/index.js +19 -0
  137. package/dist/realtime/subscriptions/index.js.map +1 -0
  138. package/dist/realtime/subscriptions/skywalker.subscription.d.ts +4 -0
  139. package/dist/realtime/subscriptions/skywalker.subscription.js +13 -0
  140. package/dist/realtime/subscriptions/skywalker.subscription.js.map +1 -0
  141. package/dist/realtime/topic-map.js +71 -0
  142. package/dist/realtime/topic.js +80 -0
  143. package/dist/repositories/account.repository.js +261 -0
  144. package/dist/repositories/direct-thread.repository.js +247 -0
  145. package/dist/repositories/direct.repository.js +153 -0
  146. package/dist/repositories/feed.repository.js +233 -0
  147. package/dist/repositories/friendship.repository.js +190 -0
  148. package/dist/repositories/hashtag.repository.js +101 -0
  149. package/dist/repositories/highlights.repository.js +127 -0
  150. package/dist/repositories/location.repository.js +84 -0
  151. package/dist/repositories/media.repository.js +165 -0
  152. package/dist/repositories/story.repository.js +156 -0
  153. package/dist/repositories/upload.repository.js +167 -0
  154. package/dist/repositories/user.repository.js +94 -0
  155. package/dist/sendmedia/index.js +11 -0
  156. package/dist/sendmedia/sendFile.js +154 -0
  157. package/dist/sendmedia/sendPhoto.js +145 -0
  158. package/dist/sendmedia/uploadPhoto.js +175 -0
  159. package/dist/sendmedia/uploadfFile.js +264 -0
  160. package/dist/services/live.service.js +147 -0
  161. package/dist/services/search.service.js +116 -0
  162. package/dist/shared/index.js +35 -0
  163. package/dist/shared/shared.js +86 -0
  164. package/dist/thrift/index.d.ts +3 -0
  165. package/dist/thrift/index.js +20 -0
  166. package/dist/thrift/index.js.map +1 -0
  167. package/dist/thrift/thrift.d.ts +59 -0
  168. package/dist/thrift/thrift.js +101 -0
  169. package/dist/thrift/thrift.js.map +1 -0
  170. package/dist/thrift/thrift.reading.d.ts +41 -0
  171. package/dist/thrift/thrift.reading.js +327 -0
  172. package/dist/thrift/thrift.reading.js.map +1 -0
  173. package/dist/thrift/thrift.writing.d.ts +44 -0
  174. package/dist/thrift/thrift.writing.js +342 -0
  175. package/dist/thrift/thrift.writing.js.map +1 -0
  176. package/dist/types/index.js +285 -0
  177. package/dist/useMultiFileAuthState.js +437 -0
  178. package/dist/utils/helper-1.js +1 -0
  179. package/dist/utils/helper-10.js +1 -0
  180. package/dist/utils/helper-11.js +1 -0
  181. package/dist/utils/helper-12.js +1 -0
  182. package/dist/utils/helper-13.js +1 -0
  183. package/dist/utils/helper-14.js +1 -0
  184. package/dist/utils/helper-15.js +1 -0
  185. package/dist/utils/helper-16.js +1 -0
  186. package/dist/utils/helper-17.js +1 -0
  187. package/dist/utils/helper-18.js +1 -0
  188. package/dist/utils/helper-19.js +1 -0
  189. package/dist/utils/helper-2.js +1 -0
  190. package/dist/utils/helper-20.js +1 -0
  191. package/dist/utils/helper-21.js +1 -0
  192. package/dist/utils/helper-22.js +1 -0
  193. package/dist/utils/helper-23.js +1 -0
  194. package/dist/utils/helper-24.js +1 -0
  195. package/dist/utils/helper-25.js +1 -0
  196. package/dist/utils/helper-26.js +1 -0
  197. package/dist/utils/helper-27.js +1 -0
  198. package/dist/utils/helper-28.js +1 -0
  199. package/dist/utils/helper-29.js +1 -0
  200. package/dist/utils/helper-3.js +1 -0
  201. package/dist/utils/helper-30.js +1 -0
  202. package/dist/utils/helper-4.js +1 -0
  203. package/dist/utils/helper-5.js +1 -0
  204. package/dist/utils/helper-6.js +1 -0
  205. package/dist/utils/helper-7.js +1 -0
  206. package/dist/utils/helper-8.js +1 -0
  207. package/dist/utils/helper-9.js +1 -0
  208. package/dist/utils/index.js +280 -0
  209. package/examples/listen-to-messages.js +86 -0
  210. 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