abmqtts 0.0.7 → 0.0.8

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.
@@ -5,244 +5,193 @@ const constants_1 = require("../constants");
5
5
  const commands_1 = require("./commands");
6
6
  const shared_1 = require("../shared");
7
7
  const mqttot_1 = require("../mqttot");
8
- const obmqtt_1 = require("abmqtt-dist");
8
+ const obmqtt_1 = require("obmqtt");
9
9
  const errors_1 = require("../errors");
10
10
  const eventemitter3_1 = require("eventemitter3");
11
11
  const mixins_1 = require("./mixins");
12
12
  class RealtimeClient extends eventemitter3_1.EventEmitter {
13
- get mqtt() {
14
- return this._mqtt;
15
- }
16
- /**
17
- *
18
- * @param {IgApiClient} ig
19
- * @param mixins - by default MessageSync and Realtime mixins are used
20
- */
21
- constructor(
22
- ig,
23
- mixins = [new mixins_1.MessageSyncMixin(), new mixins_1.RealtimeSubMixin()]
24
- ) {
25
- super();
26
- this.realtimeDebug = (0, shared_1.debugChannel)("realtime");
27
- this.messageDebug = this.realtimeDebug.extend("message");
28
- this.safeDisconnect = false;
29
- this.emitError = (e) => this.emit("error", e);
30
- this.emitWarning = (e) => this.emit("warning", e);
31
- this.ig = ig;
32
- this.realtimeDebug(
33
- `Applying mixins: ${mixins.map((m) => m.name).join(", ")}`
34
- );
35
- (0, mixins_1.applyMixins)(mixins, this, this.ig);
36
- }
37
- setInitOptions(initOptions) {
38
- if (Array.isArray(initOptions)) initOptions = { graphQlSubs: initOptions };
39
- this.initOptions = {
40
- graphQlSubs: [],
41
- skywalkerSubs: [],
42
- ...(initOptions || {}),
43
- socksOptions:
44
- typeof initOptions === "object" && !Array.isArray(initOptions)
45
- ? initOptions.socksOptions
46
- : undefined,
47
- };
48
- }
49
- constructConnection() {
50
- const userAgent = this.ig.state.appUserAgent;
51
- const deviceId = this.ig.state.phoneId;
52
- const sessionid =
53
- this.ig.state.parsedAuthorization?.sessionid ??
54
- this.ig.state.extractCookieValue("sessionid");
55
- const password = `sessionid=${sessionid}`;
56
- this.connection = new mqttot_1.MQTToTConnection({
57
- clientIdentifier: deviceId.substring(0, 20),
58
- clientInfo: {
59
- userId: BigInt(Number(this.ig.state.cookieUserId)),
60
- userAgent,
61
- clientCapabilities: 183,
62
- endpointCapabilities: 0,
63
- publishFormat: 1,
64
- noAutomaticForeground: false,
65
- makeUserAvailableInForeground: true,
66
- deviceId,
67
- isInitiallyForeground: true,
68
- networkType: 1,
69
- networkSubtype: 0,
70
- clientMqttSessionId: BigInt(Date.now()) & BigInt(0xffffffff),
71
- subscribeTopics: [88, 135, 149, 150, 133, 146],
72
- clientType: "cookie_auth",
73
- appId: BigInt(567067343352427),
74
- deviceSecret: "",
75
- clientStack: 3,
76
- ...(this.initOptions?.connectOverrides || {}),
77
- },
78
- password,
79
- appSpecificInfo: {
80
- app_version: this.ig.state.appVersion,
81
- "X-IG-Capabilities": this.ig.state.capabilitiesHeader,
82
- everclear_subscriptions: JSON.stringify({
83
- inapp_notification_subscribe_comment: "17899377895239777",
84
- inapp_notification_subscribe_comment_mention_and_reply:
85
- "17899377895239777",
86
- video_call_participant_state_delivery: "17977239895057311",
87
- presence_subscribe: "17846944882223835",
88
- }),
89
- "User-Agent": userAgent,
90
- "Accept-Language": this.ig.state.language.replace("_", "-"),
91
- platform: "android",
92
- ig_mqtt_route: "django",
93
- pubsub_msg_type_blacklist: "direct, typing_type",
94
- auth_cache_enabled: "0",
95
- },
96
- });
97
- }
98
- async connect(initOptions) {
99
- this.realtimeDebug("Connecting to realtime-broker...");
100
- this.setInitOptions(initOptions);
101
- this.realtimeDebug(
102
- `Overriding: ${Object.keys(this.initOptions?.connectOverrides || {}).join(
103
- ", "
104
- )}`
105
- );
106
- this._mqtt = new mqttot_1.MQTToTClient({
107
- url: constants_1.REALTIME.HOST_NAME_V6,
108
- payloadProvider: () => {
109
- this.constructConnection();
110
- if (!this.connection) {
111
- throw new obmqtt_1.IllegalStateError(
112
- "constructConnection() didn't create a connection"
113
- );
114
- }
115
- return (0, shared_1.compressDeflate)(this.connection.toThrift());
116
- },
117
- enableTrace: this.initOptions?.enableTrace,
118
- autoReconnect: this.initOptions?.autoReconnect ?? true,
119
- requirePayload: false,
120
- socksOptions: this.initOptions?.socksOptions,
121
- additionalOptions: this.initOptions?.additionalTlsOptions,
122
- });
123
- this.commands = new commands_1.Commands(this.mqtt);
124
- this.direct = new commands_1.DirectCommands(this.mqtt);
125
- this.mqtt.on("message", async (msg) => {
126
- const unzipped = await (0, shared_1.tryUnzipAsync)(msg.payload);
127
- const topic = constants_1.RealtimeTopicsArray.find(
128
- (t) => t.id === msg.topic
129
- );
130
- if (topic && topic.parser && !topic.noParse) {
131
- const parsedMessages = topic.parser.parseMessage(topic, unzipped);
132
- this.messageDebug(
133
- `Received on ${topic.path}: ${JSON.stringify(
134
- Array.isArray(parsedMessages)
135
- ? parsedMessages.map((x) => x.data)
136
- : parsedMessages.data
137
- )}`
138
- );
139
- this.emit(
140
- "receive",
141
- topic,
142
- Array.isArray(parsedMessages) ? parsedMessages : [parsedMessages]
143
- );
144
- } else {
145
- this.messageDebug(
146
- `Received raw on ${topic?.path ?? msg.topic}: (${
147
- unzipped.byteLength
148
- } bytes) ${(0, shared_1.prepareLogString)(unzipped.toString())}`
149
- );
150
- this.emit("receiveRaw", msg);
151
- }
152
- });
153
- this.mqtt.on("error", (e) => this.emitError(e));
154
- this.mqtt.on("warning", (w) => this.emitWarning(w));
155
- this.mqtt.on("disconnect", () =>
156
- this.safeDisconnect
157
- ? this.emit("disconnect")
158
- : this.emitError(
159
- new errors_1.ClientDisconnectedError(
160
- "MQTToTClient got disconnected."
161
- )
162
- )
163
- );
164
- return new Promise((resolve, reject) => {
165
- this.mqtt.on("connect", async () => {
166
- if (!this.initOptions) {
167
- throw new obmqtt_1.IllegalStateError("No initi options given");
13
+ get mqtt() {
14
+ return this._mqtt;
15
+ }
16
+ /**
17
+ *
18
+ * @param {IgApiClient} ig
19
+ * @param mixins - by default MessageSync and Realtime mixins are used
20
+ */
21
+ constructor(ig, mixins = [new mixins_1.MessageSyncMixin(), new mixins_1.RealtimeSubMixin()]) {
22
+ super();
23
+ this.realtimeDebug = (0, shared_1.debugChannel)('realtime');
24
+ this.messageDebug = this.realtimeDebug.extend('message');
25
+ this.safeDisconnect = false;
26
+ this.emitError = (e) => this.emit('error', e);
27
+ this.emitWarning = (e) => this.emit('warning', e);
28
+ this.ig = ig;
29
+ this.realtimeDebug(`Applying mixins: ${mixins.map(m => m.name).join(', ')}`);
30
+ (0, mixins_1.applyMixins)(mixins, this, this.ig);
31
+ }
32
+ setInitOptions(initOptions) {
33
+ if (Array.isArray(initOptions))
34
+ initOptions = { graphQlSubs: initOptions };
35
+ this.initOptions = {
36
+ graphQlSubs: [],
37
+ skywalkerSubs: [],
38
+ ...(initOptions || {}),
39
+ socksOptions: typeof initOptions === 'object' && !Array.isArray(initOptions) ? initOptions.socksOptions : undefined,
40
+ };
41
+ }
42
+ constructConnection() {
43
+ const userAgent = this.ig.state.appUserAgent;
44
+ const deviceId = this.ig.state.phoneId;
45
+ const sessionid = this.ig.state.parsedAuthorization?.sessionid ?? this.ig.state.extractCookieValue('sessionid');
46
+ const password = `sessionid=${sessionid}`;
47
+ this.connection = new mqttot_1.MQTToTConnection({
48
+ clientIdentifier: deviceId.substring(0, 20),
49
+ clientInfo: {
50
+ userId: BigInt(Number(this.ig.state.cookieUserId)),
51
+ userAgent,
52
+ clientCapabilities: 183,
53
+ endpointCapabilities: 0,
54
+ publishFormat: 1,
55
+ noAutomaticForeground: false,
56
+ makeUserAvailableInForeground: true,
57
+ deviceId,
58
+ isInitiallyForeground: true,
59
+ networkType: 1,
60
+ networkSubtype: 0,
61
+ clientMqttSessionId: BigInt(Date.now()) & BigInt(0xffffffff),
62
+ subscribeTopics: [88, 135, 149, 150, 133, 146],
63
+ clientType: 'cookie_auth',
64
+ appId: BigInt(567067343352427),
65
+ deviceSecret: '',
66
+ clientStack: 3,
67
+ ...(this.initOptions?.connectOverrides || {}),
68
+ },
69
+ password,
70
+ appSpecificInfo: {
71
+ app_version: this.ig.state.appVersion,
72
+ 'X-IG-Capabilities': this.ig.state.capabilitiesHeader,
73
+ everclear_subscriptions: JSON.stringify({
74
+ inapp_notification_subscribe_comment: '17899377895239777',
75
+ inapp_notification_subscribe_comment_mention_and_reply: '17899377895239777',
76
+ video_call_participant_state_delivery: '17977239895057311',
77
+ presence_subscribe: '17846944882223835',
78
+ }),
79
+ 'User-Agent': userAgent,
80
+ 'Accept-Language': this.ig.state.language.replace('_', '-'),
81
+ platform: 'android',
82
+ ig_mqtt_route: 'django',
83
+ pubsub_msg_type_blacklist: 'direct, typing_type',
84
+ auth_cache_enabled: '0',
85
+ },
86
+ });
87
+ }
88
+ async connect(initOptions) {
89
+ this.realtimeDebug('Connecting to realtime-broker...');
90
+ this.setInitOptions(initOptions);
91
+ this.realtimeDebug(`Overriding: ${Object.keys(this.initOptions?.connectOverrides || {}).join(', ')}`);
92
+ this._mqtt = new mqttot_1.MQTToTClient({
93
+ url: constants_1.REALTIME.HOST_NAME_V6,
94
+ payloadProvider: () => {
95
+ this.constructConnection();
96
+ if (!this.connection) {
97
+ throw new obmqtt_1.IllegalStateError("constructConnection() didn't create a connection");
98
+ }
99
+ return (0, shared_1.compressDeflate)(this.connection.toThrift());
100
+ },
101
+ enableTrace: this.initOptions?.enableTrace,
102
+ autoReconnect: this.initOptions?.autoReconnect ?? true,
103
+ requirePayload: false,
104
+ socksOptions: this.initOptions?.socksOptions,
105
+ additionalOptions: this.initOptions?.additionalTlsOptions,
106
+ });
107
+ this.commands = new commands_1.Commands(this.mqtt);
108
+ this.direct = new commands_1.DirectCommands(this.mqtt);
109
+ this.mqtt.on('message', async (msg) => {
110
+ const unzipped = await (0, shared_1.tryUnzipAsync)(msg.payload);
111
+ const topic = constants_1.RealtimeTopicsArray.find(t => t.id === msg.topic);
112
+ if (topic && topic.parser && !topic.noParse) {
113
+ const parsedMessages = topic.parser.parseMessage(topic, unzipped);
114
+ this.messageDebug(`Received on ${topic.path}: ${JSON.stringify(Array.isArray(parsedMessages) ? parsedMessages.map((x) => x.data) : parsedMessages.data)}`);
115
+ this.emit('receive', topic, Array.isArray(parsedMessages) ? parsedMessages : [parsedMessages]);
116
+ }
117
+ else {
118
+ this.messageDebug(`Received raw on ${topic?.path ?? msg.topic}: (${unzipped.byteLength} bytes) ${(0, shared_1.prepareLogString)(unzipped.toString())}`);
119
+ this.emit('receiveRaw', msg);
120
+ }
121
+ });
122
+ this.mqtt.on('error', e => this.emitError(e));
123
+ this.mqtt.on('warning', w => this.emitWarning(w));
124
+ this.mqtt.on('disconnect', () => this.safeDisconnect
125
+ ? this.emit('disconnect')
126
+ : this.emitError(new errors_1.ClientDisconnectedError('MQTToTClient got disconnected.')));
127
+ return new Promise((resolve, reject) => {
128
+ this.mqtt.on('connect', async () => {
129
+ if (!this.initOptions) {
130
+ throw new obmqtt_1.IllegalStateError('No initi options given');
131
+ }
132
+ this.realtimeDebug('Connected. Checking initial subs.');
133
+ const { graphQlSubs, skywalkerSubs, irisData } = this.initOptions;
134
+ await Promise.all([
135
+ graphQlSubs && graphQlSubs.length > 0 ? this.graphQlSubscribe(graphQlSubs) : null,
136
+ skywalkerSubs && skywalkerSubs.length > 0 ? this.skywalkerSubscribe(skywalkerSubs) : null,
137
+ irisData ? this.irisSubscribe(irisData) : null,
138
+ ]).then(resolve);
139
+ });
140
+ this.mqtt.connect({
141
+ keepAlive: 20,
142
+ protocolLevel: 3,
143
+ clean: true,
144
+ connectDelay: 60 * 1000,
145
+ }).catch(e => {
146
+ this.emitError(e);
147
+ reject(e);
148
+ });
149
+ });
150
+ }
151
+ disconnect() {
152
+ this.safeDisconnect = true;
153
+ return this.mqtt?.disconnect() ?? Promise.resolve();
154
+ }
155
+ graphQlSubscribe(sub) {
156
+ sub = typeof sub === 'string' ? [sub] : sub;
157
+ if (!this.commands) {
158
+ throw new obmqtt_1.IllegalStateError('connect() must be called before graphQlSubscribe()');
168
159
  }
169
- this.realtimeDebug("Connected. Checking initial subs.");
170
- const { graphQlSubs, skywalkerSubs, irisData } = this.initOptions;
171
- await Promise.all([
172
- graphQlSubs && graphQlSubs.length > 0
173
- ? this.graphQlSubscribe(graphQlSubs)
174
- : null,
175
- skywalkerSubs && skywalkerSubs.length > 0
176
- ? this.skywalkerSubscribe(skywalkerSubs)
177
- : null,
178
- irisData ? this.irisSubscribe(irisData) : null,
179
- ]).then(resolve);
180
- });
181
- this.mqtt
182
- .connect({
183
- keepAlive: 20,
184
- protocolLevel: 3,
185
- clean: true,
186
- connectDelay: 60 * 1000,
187
- })
188
- .catch((e) => {
189
- this.emitError(e);
190
- reject(e);
160
+ this.realtimeDebug(`Subscribing with GraphQL to ${sub.join(', ')}`);
161
+ return this.commands.updateSubscriptions({
162
+ topic: constants_1.Topics.REALTIME_SUB,
163
+ data: {
164
+ sub,
165
+ },
191
166
  });
192
- });
193
- }
194
- disconnect() {
195
- this.safeDisconnect = true;
196
- return this.mqtt?.disconnect() ?? Promise.resolve();
197
- }
198
- graphQlSubscribe(sub) {
199
- sub = typeof sub === "string" ? [sub] : sub;
200
- if (!this.commands) {
201
- throw new obmqtt_1.IllegalStateError(
202
- "connect() must be called before graphQlSubscribe()"
203
- );
204
167
  }
205
- this.realtimeDebug(`Subscribing with GraphQL to ${sub.join(", ")}`);
206
- return this.commands.updateSubscriptions({
207
- topic: constants_1.Topics.REALTIME_SUB,
208
- data: {
209
- sub,
210
- },
211
- });
212
- }
213
- skywalkerSubscribe(sub) {
214
- sub = typeof sub === "string" ? [sub] : sub;
215
- if (!this.commands) {
216
- throw new obmqtt_1.IllegalStateError(
217
- "connect() must be called before skywalkerSubscribe()"
218
- );
168
+ skywalkerSubscribe(sub) {
169
+ sub = typeof sub === 'string' ? [sub] : sub;
170
+ if (!this.commands) {
171
+ throw new obmqtt_1.IllegalStateError('connect() must be called before skywalkerSubscribe()');
172
+ }
173
+ this.realtimeDebug(`Subscribing with Skywalker to ${sub.join(', ')}`);
174
+ return this.commands.updateSubscriptions({
175
+ topic: constants_1.Topics.PUBSUB,
176
+ data: {
177
+ sub,
178
+ },
179
+ });
219
180
  }
220
- this.realtimeDebug(`Subscribing with Skywalker to ${sub.join(", ")}`);
221
- return this.commands.updateSubscriptions({
222
- topic: constants_1.Topics.PUBSUB,
223
- data: {
224
- sub,
225
- },
226
- });
227
- }
228
- irisSubscribe({ seq_id, snapshot_at_ms }) {
229
- if (!this.commands) {
230
- throw new obmqtt_1.IllegalStateError(
231
- "connect() must be called before irisSubscribe()"
232
- );
181
+ irisSubscribe({ seq_id, snapshot_at_ms, }) {
182
+ if (!this.commands) {
183
+ throw new obmqtt_1.IllegalStateError('connect() must be called before irisSubscribe()');
184
+ }
185
+ this.realtimeDebug(`Iris Sub to: seqId: ${seq_id}, snapshot: ${snapshot_at_ms}`);
186
+ return this.commands.updateSubscriptions({
187
+ topic: constants_1.Topics.IRIS_SUB,
188
+ data: {
189
+ seq_id,
190
+ snapshot_at_ms,
191
+ snapshot_app_version: this.ig.state.appVersion,
192
+ },
193
+ });
233
194
  }
234
- this.realtimeDebug(
235
- `Iris Sub to: seqId: ${seq_id}, snapshot: ${snapshot_at_ms}`
236
- );
237
- return this.commands.updateSubscriptions({
238
- topic: constants_1.Topics.IRIS_SUB,
239
- data: {
240
- seq_id,
241
- snapshot_at_ms,
242
- snapshot_app_version: this.ig.state.appVersion,
243
- },
244
- });
245
- }
246
195
  }
247
196
  exports.RealtimeClient = RealtimeClient;
248
- //# sourceMappingURL=realtime.client.js.map
197
+ //# sourceMappingURL=realtime.client.js.map
package/dist/shared.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IgApiClient } from 'instagram-private-api';
2
2
  import { Debugger } from 'debug';
3
- import { MqttClient } from 'abmqtt-dist';
3
+ import { MqttClient } from 'obmqtt';
4
4
  export declare function createFbnsUserAgent(ig: IgApiClient): string;
5
5
  export declare function compressDeflate(data: string | Buffer): Promise<Buffer>;
6
6
  export declare function unzipAsync(data: string | Buffer): Promise<Buffer>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abmqtts",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Realtime and Push Notification (FBNS) support for the instagram-private-api",
5
5
  "bugs": {
6
6
  "url": "https://github.com/ozanbaskan/instagram_mqtt/issues"
@@ -37,7 +37,7 @@
37
37
  "debug": "^4.3.4",
38
38
  "eventemitter3": "^5.0.1",
39
39
  "instagram-private-api": "^1.46.1",
40
- "abmqtt-dist": "^0.0.5",
40
+ "abmqtt-dist": "^0.0.6",
41
41
  "socks": "^2.8.1",
42
42
  "ts-custom-error": "^3.3.1"
43
43
  },