nodejs-insta-private-api-mqt 1.3.91 → 1.3.92

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.
@@ -1,96 +1,76 @@
1
- const protobuf = require('protobufjs');
2
1
  const pako = require('pako');
3
2
  const debug = require('debug')('ig:proto');
3
+ const irisProto = require('./proto/iris-bundle');
4
+ const directProto = require('./proto/direct-bundle');
5
+ const igMessagesProto = require('./proto/ig-messages-bundle');
4
6
  /**
5
7
  * Protobuf Parser - Instagram MQTT messages
6
- * Simplified embedded proto without external file dependencies
8
+ * Uses compiled proto definitions from .proto files via pbjs
7
9
  */
8
10
  class ProtoParser {
9
11
  constructor() {
10
12
  this.root = null;
11
13
  this.loadedTypes = {};
14
+ this.directTypes = {};
15
+ this.igMessageTypes = {};
12
16
  this.init();
13
17
  }
14
18
  init() {
15
19
  try {
16
- // Inline proto definitions - no file dependencies
17
- const proto = `
18
- syntax = "proto3";
19
-
20
- package ig.iris;
21
-
22
- message IrisPayload {
23
- string action = 1;
24
- int64 seq_id = 2;
25
- repeated IrisItem items = 3;
26
- }
27
-
28
- message IrisItem {
29
- string id = 1;
30
- string type = 2;
31
- int64 timestamp = 3;
32
- string op = 4;
33
- string path = 5;
34
- MessageSyncMessage message = 6;
35
- ThreadUpdate thread = 7;
36
- TypingIndicator typing = 8;
37
- PresenceIndicator presence = 9;
38
- }
39
-
40
- message MessageSyncMessage {
41
- string item_id = 1;
42
- int64 user_id = 2;
43
- int64 timestamp = 3;
44
- string thread_id = 4;
45
- string thread_v2_id = 5;
46
- string item_type = 6;
47
- string text = 7;
48
- bool is_sent = 8;
49
- bool is_delivered = 9;
50
- bool is_read = 10;
51
- string emoji_reaction = 11;
52
- }
53
-
54
- message ThreadUpdate {
55
- string thread_id = 1;
56
- string thread_v2_id = 2;
57
- repeated int64 user_ids = 3;
58
- string thread_title = 4;
59
- int64 last_activity_at = 5;
60
- bool is_group = 6;
61
- bool is_archived = 7;
62
- bool is_muted = 8;
63
- string thread_type = 9;
64
- }
65
-
66
- message TypingIndicator {
67
- int64 thread_id = 1;
68
- int64 from_user_id = 2;
69
- string state = 3;
70
- int64 timestamp = 4;
71
- }
72
-
73
- message PresenceIndicator {
74
- int64 user_id = 1;
75
- string status = 2;
76
- int64 last_seen_at = 3;
77
- }
78
- `;
79
- // Parse proto definition
80
- this.root = protobuf.parse(proto).root;
81
- // Load types
20
+ const iris = irisProto.ig.iris;
21
+ const common = irisProto.ig.common;
82
22
  this.loadedTypes = {
83
- IrisPayload: this.root.lookupType('ig.iris.IrisPayload'),
84
- IrisItem: this.root.lookupType('ig.iris.IrisItem'),
85
- MessageSyncMessage: this.root.lookupType('ig.iris.MessageSyncMessage'),
86
- ThreadUpdate: this.root.lookupType('ig.iris.ThreadUpdate'),
87
- TypingIndicator: this.root.lookupType('ig.iris.TypingIndicator'),
88
- PresenceIndicator: this.root.lookupType('ig.iris.PresenceIndicator')
23
+ IrisPayload: iris.IrisPayload,
24
+ IrisItem: iris.IrisItem,
25
+ MessageSyncMessage: iris.MessageSyncMessage,
26
+ ThreadUpdate: iris.ThreadUpdate,
27
+ TypingIndicator: iris.TypingIndicator,
28
+ PresenceIndicator: iris.PresenceIndicator,
29
+ Delta: iris.Delta,
30
+ MediaData: iris.MediaData,
31
+ VoiceMediaData: iris.VoiceMediaData,
32
+ AnimatedMediaData: iris.AnimatedMediaData,
33
+ MediaShareData: iris.MediaShareData,
34
+ ReactionData: iris.ReactionData,
35
+ ReactionItem: iris.ReactionItem,
36
+ ThreadMetadata: iris.ThreadMetadata,
89
37
  };
90
- debug('✓ Proto parser initialized with', Object.keys(this.loadedTypes).length, 'types');
38
+ if (common) {
39
+ this.loadedTypes.Timestamp = common.Timestamp;
40
+ this.loadedTypes.UserId = common.UserId;
41
+ this.loadedTypes.ThreadId = common.ThreadId;
42
+ this.loadedTypes.Reaction = common.Reaction;
43
+ this.loadedTypes.MediaAttachment = common.MediaAttachment;
44
+ this.loadedTypes.Link = common.Link;
45
+ }
46
+ const direct = directProto.ig.direct;
47
+ if (direct) {
48
+ this.directTypes = {
49
+ DirectInboxMessageContent: direct.DirectInboxMessageContent,
50
+ DirectInboxMessage: direct.DirectInboxMessage,
51
+ DirectInboxThread: direct.DirectInboxThread,
52
+ DirectInbox: direct.DirectInbox,
53
+ DirectSync: direct.DirectSync,
54
+ };
55
+ }
56
+ const igMsg = igMessagesProto.ig.iris;
57
+ if (igMsg) {
58
+ this.igMessageTypes = {
59
+ DirectMessage: igMsg.DirectMessage,
60
+ DirectThread: igMsg.DirectThread,
61
+ TypingIndicator: igMsg.TypingIndicator,
62
+ PresenceStatus: igMsg.PresenceStatus,
63
+ DeltaMessage: igMsg.DeltaMessage,
64
+ Acknowledgment: igMsg.Acknowledgment,
65
+ };
66
+ }
67
+ this.root = irisProto;
68
+ debug('Proto parser initialized with', Object.keys(this.loadedTypes).length, 'iris types,',
69
+ Object.keys(this.directTypes).length, 'direct types,',
70
+ Object.keys(this.igMessageTypes).length, 'ig-message types');
91
71
  }
92
72
  catch (e) {
93
- debug('Proto init failed:', e.message);
73
+ debug('Proto init failed:', e.message);
94
74
  this.root = null;
95
75
  }
96
76
  }
@@ -107,28 +87,33 @@ message PresenceIndicator {
107
87
  }
108
88
  }
109
89
  }
90
+ _decodeWithType(TypeClass, payload) {
91
+ const buf = (payload instanceof Uint8Array) ? payload : new Uint8Array(payload);
92
+ const decoded = TypeClass.decode(buf);
93
+ return TypeClass.toObject(decoded, {
94
+ longs: String,
95
+ enums: String,
96
+ bytes: String,
97
+ defaults: true
98
+ });
99
+ }
110
100
  parsePayload(topicId, rawPayload) {
111
101
  try {
112
102
  if (!rawPayload || rawPayload.length === 0) {
113
103
  return { error: 'Empty', decoded: null };
114
104
  }
115
105
  const payload = this.decompress(rawPayload);
116
- debug(`📦 Topic ${topicId}: ${payload.length} bytes`);
106
+ debug(`Topic ${topicId}: ${payload.length} bytes`);
117
107
  if (this.loadedTypes.IrisPayload) {
118
108
  try {
119
- const decoded = this.loadedTypes.IrisPayload.decode(payload);
120
- const message = this.loadedTypes.IrisPayload.toObject(decoded, {
121
- longs: String,
122
- enums: String,
123
- bytes: String
124
- });
125
- debug(`✓ Decoded ${message.items?.length || 0} items`);
109
+ const message = this._decodeWithType(this.loadedTypes.IrisPayload, payload);
110
+ debug(`Decoded ${message.items?.length || 0} items`);
126
111
  return { decoded: message, format: 'protobuf' };
127
112
  }
128
113
  catch (e) {
129
114
  debug(`Proto decode failed, trying JSON`);
130
115
  try {
131
- const json = JSON.parse(payload.toString('utf-8'));
116
+ const json = JSON.parse(Buffer.from(payload).toString('utf-8'));
132
117
  return { decoded: json, format: 'json' };
133
118
  }
134
119
  catch (e2) {
@@ -143,6 +128,86 @@ message PresenceIndicator {
143
128
  return { error: e.message, decoded: null };
144
129
  }
145
130
  }
131
+ decode(topicId, rawPayload) {
132
+ try {
133
+ if (!rawPayload || rawPayload.length === 0) {
134
+ return { success: false, error: 'Empty', decoded: null, messages: [], raw: null };
135
+ }
136
+ const payload = this.decompress(rawPayload);
137
+ if (this.loadedTypes.IrisPayload) {
138
+ try {
139
+ const decoded = this._decodeWithType(this.loadedTypes.IrisPayload, payload);
140
+ const messages = this.extractMessages(decoded);
141
+ return { success: true, decoded, messages, format: 'protobuf' };
142
+ }
143
+ catch (e) {
144
+ try {
145
+ const text = Buffer.from(payload).toString('utf-8');
146
+ const json = JSON.parse(text);
147
+ const messages = this.extractMessages(json);
148
+ return { success: true, decoded: json, messages, format: 'json' };
149
+ }
150
+ catch (e2) {
151
+ return { success: false, error: 'Parse failed', decoded: null, messages: [], raw: Buffer.from(payload).toString('utf-8', 0, 200) };
152
+ }
153
+ }
154
+ }
155
+ return { success: false, error: 'Proto not ready', decoded: null, messages: [] };
156
+ }
157
+ catch (e) {
158
+ debug('Decode error:', e.message);
159
+ return { success: false, error: e.message, decoded: null, messages: [] };
160
+ }
161
+ }
162
+ decodeDirectSync(rawPayload) {
163
+ try {
164
+ if (!this.directTypes.DirectSync) return null;
165
+ const payload = this.decompress(rawPayload);
166
+ return this._decodeWithType(this.directTypes.DirectSync, payload);
167
+ }
168
+ catch (e) {
169
+ debug('DirectSync decode error:', e.message);
170
+ return null;
171
+ }
172
+ }
173
+ decodeDirectInbox(rawPayload) {
174
+ try {
175
+ if (!this.directTypes.DirectInbox) return null;
176
+ const payload = this.decompress(rawPayload);
177
+ return this._decodeWithType(this.directTypes.DirectInbox, payload);
178
+ }
179
+ catch (e) {
180
+ debug('DirectInbox decode error:', e.message);
181
+ return null;
182
+ }
183
+ }
184
+ decodeDeltaMessage(rawPayload) {
185
+ try {
186
+ if (!this.igMessageTypes.DeltaMessage) return null;
187
+ const payload = this.decompress(rawPayload);
188
+ return this._decodeWithType(this.igMessageTypes.DeltaMessage, payload);
189
+ }
190
+ catch (e) {
191
+ debug('DeltaMessage decode error:', e.message);
192
+ return null;
193
+ }
194
+ }
195
+ encodeIrisPayload(obj) {
196
+ try {
197
+ if (!this.loadedTypes.IrisPayload) return null;
198
+ const errMsg = this.loadedTypes.IrisPayload.verify(obj);
199
+ if (errMsg) {
200
+ debug('IrisPayload verify failed:', errMsg);
201
+ return null;
202
+ }
203
+ const message = this.loadedTypes.IrisPayload.create(obj);
204
+ return this.loadedTypes.IrisPayload.encode(message).finish();
205
+ }
206
+ catch (e) {
207
+ debug('Encode IrisPayload error:', e.message);
208
+ return null;
209
+ }
210
+ }
146
211
  extractMessages(payload) {
147
212
  if (!payload || !payload.items)
148
213
  return [];
@@ -169,16 +234,32 @@ message PresenceIndicator {
169
234
  typing: item.typing
170
235
  });
171
236
  }
237
+ if (item.presence) {
238
+ messages.push({
239
+ id: item.id,
240
+ type: 'presence',
241
+ presence: item.presence
242
+ });
243
+ }
172
244
  });
173
245
  return messages;
174
246
  }
175
247
  isReady() {
176
248
  return this.root !== null && Object.keys(this.loadedTypes).length > 0;
177
249
  }
250
+ getTypes() {
251
+ return {
252
+ iris: Object.keys(this.loadedTypes),
253
+ direct: Object.keys(this.directTypes),
254
+ igMessages: Object.keys(this.igMessageTypes),
255
+ };
256
+ }
178
257
  getStats() {
179
258
  return {
180
259
  ready: this.isReady(),
181
- types: Object.keys(this.loadedTypes).length
260
+ types: Object.keys(this.loadedTypes).length,
261
+ directTypes: Object.keys(this.directTypes).length,
262
+ igMessageTypes: Object.keys(this.igMessageTypes).length,
182
263
  };
183
264
  }
184
265
  }
@@ -1,10 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PROTO_DEFINITIONS = void 0;
4
- /**
5
- * Protobuf Definitions for Instagram MQTT Protocol
6
- * These are the message schemas used in IRIS, Skywalker, and DirectMessage topics
7
- */
4
+ exports.irisProto = void 0;
5
+ exports.directProto = void 0;
6
+ exports.igMessagesProto = void 0;
7
+ const irisBundle = require('../proto/iris-bundle');
8
+ const directBundle = require('../proto/direct-bundle');
9
+ const igMessagesBundle = require('../proto/ig-messages-bundle');
10
+ exports.irisProto = irisBundle;
11
+ exports.directProto = directBundle;
12
+ exports.igMessagesProto = igMessagesBundle;
8
13
  exports.PROTO_DEFINITIONS = {
9
14
  DirectRealtimePayload: {
10
15
  type: 'object',
@@ -42,9 +47,9 @@ exports.PROTO_DEFINITIONS = {
42
47
  type: 'object',
43
48
  fields: {
44
49
  userId: { type: 'uint64', id: 1 },
45
- status: { type: 'string', id: 2 }, // online, offline, away
50
+ status: { type: 'string', id: 2 },
46
51
  lastActivity: { type: 'uint64', id: 3 },
47
- device: { type: 'string', id: 4 }, // mobile, web, unknown
52
+ device: { type: 'string', id: 4 },
48
53
  }
49
54
  },
50
55
  TypingIndicator: {
@@ -64,7 +69,7 @@ exports.PROTO_DEFINITIONS = {
64
69
  userId: { type: 'uint64', id: 3 },
65
70
  emoji: { type: 'string', id: 4 },
66
71
  timestamp: { type: 'uint64', id: 5 },
67
- operation: { type: 'string', id: 6 }, // add, remove
72
+ operation: { type: 'string', id: 6 },
68
73
  }
69
74
  },
70
75
  ClientPayload: {
@@ -77,4 +82,10 @@ exports.PROTO_DEFINITIONS = {
77
82
  subscribeProtoMask: { type: 'uint32', id: 5 },
78
83
  }
79
84
  },
85
+ compiled: {
86
+ iris: irisBundle.ig?.iris || {},
87
+ direct: directBundle.ig?.direct || {},
88
+ common: irisBundle.ig?.common || {},
89
+ igMessages: igMessagesBundle.ig?.iris || {},
90
+ },
80
91
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodejs-insta-private-api-mqt",
3
- "version": "1.3.91",
3
+ "version": "1.3.92",
4
4
  "description": "Complete Instagram MQTT protocol with full-featured REALTIME and REST API — all in one project.",
5
5
 
6
6
  "main": "dist/dist/index.js",