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,83 @@
|
|
|
1
|
+
// Instagram Direct Messages Protocol (Protobuf)
|
|
2
|
+
// Used for real-time message sync via MQTT
|
|
3
|
+
|
|
4
|
+
syntax = "proto3";
|
|
5
|
+
|
|
6
|
+
package ig.iris;
|
|
7
|
+
|
|
8
|
+
// DirectMessage - Single message in a thread
|
|
9
|
+
message DirectMessage {
|
|
10
|
+
int64 message_id = 1;
|
|
11
|
+
int64 user_id = 2;
|
|
12
|
+
string content = 3;
|
|
13
|
+
int64 timestamp = 4;
|
|
14
|
+
|
|
15
|
+
// Message type: text, photo, video, etc.
|
|
16
|
+
string type = 5;
|
|
17
|
+
|
|
18
|
+
// Reactions: emoji -> count
|
|
19
|
+
map<string, int32> reactions = 6;
|
|
20
|
+
|
|
21
|
+
// Whether user has seen
|
|
22
|
+
bool is_sent = 7;
|
|
23
|
+
bool is_delivered = 8;
|
|
24
|
+
bool is_read = 9;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// DirectThread - Conversation thread
|
|
28
|
+
message DirectThread {
|
|
29
|
+
int64 thread_id = 1;
|
|
30
|
+
repeated int64 participant_ids = 2;
|
|
31
|
+
string thread_title = 3;
|
|
32
|
+
int64 last_message_ts = 4;
|
|
33
|
+
|
|
34
|
+
// Admin user ID
|
|
35
|
+
int64 admin_user_id = 5;
|
|
36
|
+
|
|
37
|
+
// Is group thread
|
|
38
|
+
bool is_group = 6;
|
|
39
|
+
|
|
40
|
+
// Is archived
|
|
41
|
+
bool is_archived = 7;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// TypingIndicator - User typing signal
|
|
45
|
+
message TypingIndicator {
|
|
46
|
+
int64 thread_id = 1;
|
|
47
|
+
int64 from_user_id = 2;
|
|
48
|
+
int64 timestamp = 3;
|
|
49
|
+
|
|
50
|
+
// 0 = typing, 1 = stopped
|
|
51
|
+
int32 state = 4;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// PresenceStatus - User online/offline
|
|
55
|
+
message PresenceStatus {
|
|
56
|
+
int64 user_id = 1;
|
|
57
|
+
|
|
58
|
+
// 0 = offline, 1 = active, 2 = idle
|
|
59
|
+
int32 status = 2;
|
|
60
|
+
|
|
61
|
+
int64 timestamp = 3;
|
|
62
|
+
int64 last_active = 4;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// DeltaMessage - Incremental sync update
|
|
66
|
+
message DeltaMessage {
|
|
67
|
+
int64 sequence_id = 1;
|
|
68
|
+
string operation = 2; // add, update, delete
|
|
69
|
+
|
|
70
|
+
oneof data {
|
|
71
|
+
DirectMessage message = 3;
|
|
72
|
+
DirectThread thread = 4;
|
|
73
|
+
TypingIndicator typing = 5;
|
|
74
|
+
PresenceStatus presence = 6;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Acknowledgment - Server expects ACK for delivery
|
|
79
|
+
message Acknowledgment {
|
|
80
|
+
int64 message_id = 1;
|
|
81
|
+
int64 thread_id = 2;
|
|
82
|
+
int64 timestamp = 3;
|
|
83
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package ig.iris;
|
|
4
|
+
|
|
5
|
+
import "common.proto";
|
|
6
|
+
|
|
7
|
+
// Real Instagram Iris Protocol - Direct Messages & Realtime
|
|
8
|
+
// Based on reverse-engineered instagram_mqtt package
|
|
9
|
+
|
|
10
|
+
message IrisPayload {
|
|
11
|
+
string action = 1;
|
|
12
|
+
int64 seq_id = 2;
|
|
13
|
+
repeated IrisItem items = 3;
|
|
14
|
+
map<string, string> metadata = 4;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
message IrisItem {
|
|
18
|
+
string id = 1;
|
|
19
|
+
string type = 2; // message, thread, typing, presence, deletion
|
|
20
|
+
int64 timestamp = 3;
|
|
21
|
+
|
|
22
|
+
oneof data {
|
|
23
|
+
MessageSyncMessage message = 4;
|
|
24
|
+
ThreadUpdate thread = 5;
|
|
25
|
+
TypingIndicator typing = 6;
|
|
26
|
+
PresenceIndicator presence = 7;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
string op = 8; // add, replace, delete
|
|
30
|
+
string path = 9; // JSON path to item
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Message from sync - includes text, media, reactions
|
|
34
|
+
message MessageSyncMessage {
|
|
35
|
+
string item_id = 1;
|
|
36
|
+
int64 user_id = 2;
|
|
37
|
+
int64 timestamp = 3;
|
|
38
|
+
|
|
39
|
+
string thread_id = 4;
|
|
40
|
+
string thread_v2_id = 5;
|
|
41
|
+
|
|
42
|
+
// Message type: text, media, like, hashtag, media_share, location, voice_media, animated_media
|
|
43
|
+
string item_type = 6;
|
|
44
|
+
string text = 7;
|
|
45
|
+
|
|
46
|
+
// Media references
|
|
47
|
+
MediaData media = 8;
|
|
48
|
+
VoiceMediaData voice_media = 9;
|
|
49
|
+
AnimatedMediaData animated_media = 10;
|
|
50
|
+
MediaShareData media_share = 11;
|
|
51
|
+
|
|
52
|
+
// Reactions
|
|
53
|
+
ReactionData reactions = 12;
|
|
54
|
+
|
|
55
|
+
// Metadata
|
|
56
|
+
bool is_sent = 13;
|
|
57
|
+
bool is_delivered = 14;
|
|
58
|
+
bool is_read = 15;
|
|
59
|
+
|
|
60
|
+
// Voice/Video Call info
|
|
61
|
+
string raven_media_type = 16;
|
|
62
|
+
map<string, string> extra_data = 17;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
message MediaData {
|
|
66
|
+
string id = 1;
|
|
67
|
+
int32 media_type = 2; // 1=image, 2=video, 8=album
|
|
68
|
+
|
|
69
|
+
int32 original_width = 3;
|
|
70
|
+
int32 original_height = 4;
|
|
71
|
+
|
|
72
|
+
repeated string image_urls = 5;
|
|
73
|
+
repeated string video_urls = 6;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
message VoiceMediaData {
|
|
77
|
+
string id = 1;
|
|
78
|
+
string audio_src = 2;
|
|
79
|
+
int32 duration = 3;
|
|
80
|
+
repeated int32 waveform_data = 4;
|
|
81
|
+
|
|
82
|
+
bool seen = 5;
|
|
83
|
+
int32 seen_count = 6;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
message AnimatedMediaData {
|
|
87
|
+
string id = 1;
|
|
88
|
+
string url = 2;
|
|
89
|
+
bool is_sticker = 3;
|
|
90
|
+
bool is_random = 4;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
message MediaShareData {
|
|
94
|
+
string id = 1;
|
|
95
|
+
string code = 2;
|
|
96
|
+
int32 media_type = 3;
|
|
97
|
+
|
|
98
|
+
int32 original_width = 4;
|
|
99
|
+
int32 original_height = 5;
|
|
100
|
+
|
|
101
|
+
string caption = 6;
|
|
102
|
+
int32 like_count = 7;
|
|
103
|
+
int32 comment_count = 8;
|
|
104
|
+
int64 taken_at = 9;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
message ReactionData {
|
|
108
|
+
map<int64, string> emojis = 1; // user_id -> emoji
|
|
109
|
+
int32 likes_count = 2;
|
|
110
|
+
int32 emojis_count = 3;
|
|
111
|
+
|
|
112
|
+
repeated ReactionItem likes = 4;
|
|
113
|
+
repeated ReactionItem emoji_reactions = 5;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
message ReactionItem {
|
|
117
|
+
int64 sender_id = 1;
|
|
118
|
+
int64 timestamp = 2;
|
|
119
|
+
string client_context = 3;
|
|
120
|
+
string emoji = 4;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Thread Update - conversation data
|
|
124
|
+
message ThreadUpdate {
|
|
125
|
+
string thread_id = 1;
|
|
126
|
+
string thread_v2_id = 2;
|
|
127
|
+
|
|
128
|
+
// Participants
|
|
129
|
+
repeated int64 user_ids = 3;
|
|
130
|
+
repeated int64 left_user_ids = 4;
|
|
131
|
+
repeated int64 admin_user_ids = 5;
|
|
132
|
+
|
|
133
|
+
// Thread info
|
|
134
|
+
string thread_title = 6;
|
|
135
|
+
int64 last_activity_at = 7;
|
|
136
|
+
|
|
137
|
+
bool is_group = 8;
|
|
138
|
+
bool is_archived = 9;
|
|
139
|
+
bool is_muted = 10;
|
|
140
|
+
bool is_pinned = 11;
|
|
141
|
+
bool is_spam = 12;
|
|
142
|
+
|
|
143
|
+
string thread_type = 13; // private, group
|
|
144
|
+
int32 folder = 14;
|
|
145
|
+
|
|
146
|
+
// Last message in thread
|
|
147
|
+
MessageSyncMessage last_message = 15;
|
|
148
|
+
|
|
149
|
+
// Pagination
|
|
150
|
+
bool has_older = 16;
|
|
151
|
+
bool has_newer = 17;
|
|
152
|
+
string newest_cursor = 18;
|
|
153
|
+
string oldest_cursor = 19;
|
|
154
|
+
string next_cursor = 20;
|
|
155
|
+
|
|
156
|
+
map<string, ThreadMetadata> metadata = 21;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
message ThreadMetadata {
|
|
160
|
+
string key = 1;
|
|
161
|
+
string value = 2;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Typing indicator
|
|
165
|
+
message TypingIndicator {
|
|
166
|
+
int64 thread_id = 1;
|
|
167
|
+
int64 from_user_id = 2;
|
|
168
|
+
string state = 3; // started, stopped
|
|
169
|
+
int64 timestamp = 4;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// User presence indicator
|
|
173
|
+
message PresenceIndicator {
|
|
174
|
+
int64 user_id = 1;
|
|
175
|
+
string status = 2; // active, inactive
|
|
176
|
+
int64 last_seen_at = 3;
|
|
177
|
+
int64 timestamp = 4;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Delta - incremental update
|
|
181
|
+
message Delta {
|
|
182
|
+
string operation = 1; // add, update, delete
|
|
183
|
+
string path = 2;
|
|
184
|
+
|
|
185
|
+
IrisItem item = 3;
|
|
186
|
+
|
|
187
|
+
map<string, string> context = 4;
|
|
188
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
const protobuf = require('protobufjs');
|
|
2
|
+
const pako = require('pako');
|
|
3
|
+
const debug = require('debug')('ig:proto');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Protobuf Parser - Instagram MQTT messages
|
|
7
|
+
* Simplified embedded proto without external file dependencies
|
|
8
|
+
*/
|
|
9
|
+
class ProtoParser {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.root = null;
|
|
12
|
+
this.loadedTypes = {};
|
|
13
|
+
this.init();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
init() {
|
|
17
|
+
try {
|
|
18
|
+
// Inline proto definitions - no file dependencies
|
|
19
|
+
const proto = `
|
|
20
|
+
syntax = "proto3";
|
|
21
|
+
|
|
22
|
+
package ig.iris;
|
|
23
|
+
|
|
24
|
+
message IrisPayload {
|
|
25
|
+
string action = 1;
|
|
26
|
+
int64 seq_id = 2;
|
|
27
|
+
repeated IrisItem items = 3;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
message IrisItem {
|
|
31
|
+
string id = 1;
|
|
32
|
+
string type = 2;
|
|
33
|
+
int64 timestamp = 3;
|
|
34
|
+
string op = 4;
|
|
35
|
+
string path = 5;
|
|
36
|
+
MessageSyncMessage message = 6;
|
|
37
|
+
ThreadUpdate thread = 7;
|
|
38
|
+
TypingIndicator typing = 8;
|
|
39
|
+
PresenceIndicator presence = 9;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
message MessageSyncMessage {
|
|
43
|
+
string item_id = 1;
|
|
44
|
+
int64 user_id = 2;
|
|
45
|
+
int64 timestamp = 3;
|
|
46
|
+
string thread_id = 4;
|
|
47
|
+
string thread_v2_id = 5;
|
|
48
|
+
string item_type = 6;
|
|
49
|
+
string text = 7;
|
|
50
|
+
bool is_sent = 8;
|
|
51
|
+
bool is_delivered = 9;
|
|
52
|
+
bool is_read = 10;
|
|
53
|
+
string emoji_reaction = 11;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
message ThreadUpdate {
|
|
57
|
+
string thread_id = 1;
|
|
58
|
+
string thread_v2_id = 2;
|
|
59
|
+
repeated int64 user_ids = 3;
|
|
60
|
+
string thread_title = 4;
|
|
61
|
+
int64 last_activity_at = 5;
|
|
62
|
+
bool is_group = 6;
|
|
63
|
+
bool is_archived = 7;
|
|
64
|
+
bool is_muted = 8;
|
|
65
|
+
string thread_type = 9;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
message TypingIndicator {
|
|
69
|
+
int64 thread_id = 1;
|
|
70
|
+
int64 from_user_id = 2;
|
|
71
|
+
string state = 3;
|
|
72
|
+
int64 timestamp = 4;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
message PresenceIndicator {
|
|
76
|
+
int64 user_id = 1;
|
|
77
|
+
string status = 2;
|
|
78
|
+
int64 last_seen_at = 3;
|
|
79
|
+
}
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
// Parse proto definition
|
|
83
|
+
this.root = protobuf.parse(proto).root;
|
|
84
|
+
|
|
85
|
+
// Load types
|
|
86
|
+
this.loadedTypes = {
|
|
87
|
+
IrisPayload: this.root.lookupType('ig.iris.IrisPayload'),
|
|
88
|
+
IrisItem: this.root.lookupType('ig.iris.IrisItem'),
|
|
89
|
+
MessageSyncMessage: this.root.lookupType('ig.iris.MessageSyncMessage'),
|
|
90
|
+
ThreadUpdate: this.root.lookupType('ig.iris.ThreadUpdate'),
|
|
91
|
+
TypingIndicator: this.root.lookupType('ig.iris.TypingIndicator'),
|
|
92
|
+
PresenceIndicator: this.root.lookupType('ig.iris.PresenceIndicator')
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
debug('✓ Proto parser initialized with', Object.keys(this.loadedTypes).length, 'types');
|
|
96
|
+
} catch (e) {
|
|
97
|
+
debug('❌ Proto init failed:', e.message);
|
|
98
|
+
this.root = null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
decompress(buffer) {
|
|
103
|
+
try {
|
|
104
|
+
return pako.inflate(buffer);
|
|
105
|
+
} catch (e) {
|
|
106
|
+
try {
|
|
107
|
+
return pako.ungzip(buffer);
|
|
108
|
+
} catch (e2) {
|
|
109
|
+
return buffer;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
parsePayload(topicId, rawPayload) {
|
|
115
|
+
try {
|
|
116
|
+
if (!rawPayload || rawPayload.length === 0) {
|
|
117
|
+
return { error: 'Empty', decoded: null };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const payload = this.decompress(rawPayload);
|
|
121
|
+
debug(`📦 Topic ${topicId}: ${payload.length} bytes`);
|
|
122
|
+
|
|
123
|
+
if (this.loadedTypes.IrisPayload) {
|
|
124
|
+
try {
|
|
125
|
+
const decoded = this.loadedTypes.IrisPayload.decode(payload);
|
|
126
|
+
const message = this.loadedTypes.IrisPayload.toObject(decoded, {
|
|
127
|
+
longs: String,
|
|
128
|
+
enums: String,
|
|
129
|
+
bytes: String
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
debug(`✓ Decoded ${message.items?.length || 0} items`);
|
|
133
|
+
return { decoded: message, format: 'protobuf' };
|
|
134
|
+
} catch (e) {
|
|
135
|
+
debug(`Proto decode failed, trying JSON`);
|
|
136
|
+
try {
|
|
137
|
+
const json = JSON.parse(payload.toString('utf-8'));
|
|
138
|
+
return { decoded: json, format: 'json' };
|
|
139
|
+
} catch (e2) {
|
|
140
|
+
return { error: 'Parse failed', decoded: null };
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return { error: 'Proto not ready', decoded: null };
|
|
146
|
+
} catch (e) {
|
|
147
|
+
debug('Parse error:', e.message);
|
|
148
|
+
return { error: e.message, decoded: null };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
extractMessages(payload) {
|
|
153
|
+
if (!payload || !payload.items) return [];
|
|
154
|
+
|
|
155
|
+
const messages = [];
|
|
156
|
+
payload.items.forEach(item => {
|
|
157
|
+
if (item.message) {
|
|
158
|
+
messages.push({
|
|
159
|
+
id: item.id,
|
|
160
|
+
type: 'message',
|
|
161
|
+
message: item.message
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (item.thread) {
|
|
165
|
+
messages.push({
|
|
166
|
+
id: item.id,
|
|
167
|
+
type: 'thread',
|
|
168
|
+
thread: item.thread
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (item.typing) {
|
|
172
|
+
messages.push({
|
|
173
|
+
id: item.id,
|
|
174
|
+
type: 'typing',
|
|
175
|
+
typing: item.typing
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
return messages;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
isReady() {
|
|
184
|
+
return this.root !== null && Object.keys(this.loadedTypes).length > 0;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
getStats() {
|
|
188
|
+
return {
|
|
189
|
+
ready: this.isReady(),
|
|
190
|
+
types: Object.keys(this.loadedTypes).length
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
module.exports = ProtoParser;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IrisHandshake = void 0;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
const shared_1 = require("../../shared");
|
|
6
|
+
/**
|
|
7
|
+
* IRIS Handshake - Instagram Real-time Iris Sync Protocol
|
|
8
|
+
* Handles authentication and subscription to IRIS topics
|
|
9
|
+
*/
|
|
10
|
+
class IrisHandshake {
|
|
11
|
+
constructor(client) {
|
|
12
|
+
this.irisDebug = (0, shared_1.debugChannel)('realtime', 'iris');
|
|
13
|
+
this.client = client;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create IRIS client payload for handshake
|
|
17
|
+
*/
|
|
18
|
+
createClientPayload() {
|
|
19
|
+
return {
|
|
20
|
+
clientVersion: '311.0.0.0',
|
|
21
|
+
clientUserID: this.client.ig.state.cookieUserId,
|
|
22
|
+
clientContext: {
|
|
23
|
+
clientContextVersion: '1',
|
|
24
|
+
clientContextType: 'mobile',
|
|
25
|
+
appVersion: '311.0.0.0',
|
|
26
|
+
userAgent: this.client.ig.state.appUserAgent,
|
|
27
|
+
},
|
|
28
|
+
subscribeProtoMask: 0,
|
|
29
|
+
capabilities: {
|
|
30
|
+
supportsPresenceEvents: true,
|
|
31
|
+
supportsTypingIndicators: true,
|
|
32
|
+
supportsMessageReactions: true,
|
|
33
|
+
supportsForegroundState: true,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Generate IRIS subscription request
|
|
39
|
+
*/
|
|
40
|
+
generateSubscriptionRequest(topics) {
|
|
41
|
+
this.irisDebug(`Generating IRIS subscription for topics: ${topics.join(', ')}`);
|
|
42
|
+
return {
|
|
43
|
+
requestId: (0, uuid_1.v4)(),
|
|
44
|
+
clientVersion: '311.0.0.0',
|
|
45
|
+
subscriptions: topics.map(topic => ({
|
|
46
|
+
topic,
|
|
47
|
+
active: true,
|
|
48
|
+
priority: 10,
|
|
49
|
+
})),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Handle IRIS response
|
|
54
|
+
*/
|
|
55
|
+
handleIrisResponse(data) {
|
|
56
|
+
try {
|
|
57
|
+
const response = typeof data === 'string' ? JSON.parse(data) : data;
|
|
58
|
+
this.irisDebug(`IRIS Response: ${response.type || 'unknown'}`);
|
|
59
|
+
|
|
60
|
+
if (response.type === 'heartbeat') {
|
|
61
|
+
this.client.emit('iris_heartbeat', response);
|
|
62
|
+
} else if (response.type === 'error') {
|
|
63
|
+
this.client.emit('error', new Error(`IRIS Error: ${response.message}`));
|
|
64
|
+
} else if (response.type === 'subscription_response') {
|
|
65
|
+
this.client.emit('iris_subscription', response);
|
|
66
|
+
}
|
|
67
|
+
return response;
|
|
68
|
+
} catch (err) {
|
|
69
|
+
this.irisDebug(`Failed to parse IRIS response: ${err.message}`);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.IrisHandshake = IrisHandshake;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
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
|
+
*/
|
|
8
|
+
exports.PROTO_DEFINITIONS = {
|
|
9
|
+
DirectRealtimePayload: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
fields: {
|
|
12
|
+
messageType: { type: 'uint32', id: 1 },
|
|
13
|
+
payload: { type: 'bytes', id: 2 },
|
|
14
|
+
timestamp: { type: 'uint64', id: 3 },
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
IrisMessage: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
fields: {
|
|
20
|
+
messageId: { type: 'string', id: 1 },
|
|
21
|
+
threadId: { type: 'string', id: 2 },
|
|
22
|
+
userId: { type: 'uint64', id: 3 },
|
|
23
|
+
text: { type: 'string', id: 4 },
|
|
24
|
+
timestamp: { type: 'uint64', id: 5 },
|
|
25
|
+
itemType: { type: 'string', id: 6 },
|
|
26
|
+
mediaId: { type: 'string', id: 7 },
|
|
27
|
+
isDelivered: { type: 'bool', id: 8 },
|
|
28
|
+
isSeen: { type: 'bool', id: 9 },
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
SkywalkerCommand: {
|
|
32
|
+
type: 'object',
|
|
33
|
+
fields: {
|
|
34
|
+
action: { type: 'string', id: 1 },
|
|
35
|
+
threadId: { type: 'string', id: 2 },
|
|
36
|
+
data: { type: 'bytes', id: 3 },
|
|
37
|
+
timestamp: { type: 'uint64', id: 4 },
|
|
38
|
+
clientContext: { type: 'string', id: 5 },
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
PresenceEvent: {
|
|
42
|
+
type: 'object',
|
|
43
|
+
fields: {
|
|
44
|
+
userId: { type: 'uint64', id: 1 },
|
|
45
|
+
status: { type: 'string', id: 2 }, // online, offline, away
|
|
46
|
+
lastActivity: { type: 'uint64', id: 3 },
|
|
47
|
+
device: { type: 'string', id: 4 }, // mobile, web, unknown
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
TypingIndicator: {
|
|
51
|
+
type: 'object',
|
|
52
|
+
fields: {
|
|
53
|
+
threadId: { type: 'string', id: 1 },
|
|
54
|
+
userId: { type: 'uint64', id: 2 },
|
|
55
|
+
isTyping: { type: 'bool', id: 3 },
|
|
56
|
+
timestamp: { type: 'uint64', id: 4 },
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
MessageReaction: {
|
|
60
|
+
type: 'object',
|
|
61
|
+
fields: {
|
|
62
|
+
messageId: { type: 'string', id: 1 },
|
|
63
|
+
threadId: { type: 'string', id: 2 },
|
|
64
|
+
userId: { type: 'uint64', id: 3 },
|
|
65
|
+
emoji: { type: 'string', id: 4 },
|
|
66
|
+
timestamp: { type: 'uint64', id: 5 },
|
|
67
|
+
operation: { type: 'string', id: 6 }, // add, remove
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
ClientPayload: {
|
|
71
|
+
type: 'object',
|
|
72
|
+
fields: {
|
|
73
|
+
clientVersion: { type: 'string', id: 1 },
|
|
74
|
+
clientUserID: { type: 'uint64', id: 2 },
|
|
75
|
+
clientContext: { type: 'object', id: 3 },
|
|
76
|
+
capabilities: { type: 'object', id: 4 },
|
|
77
|
+
subscribeProtoMask: { type: 'uint32', id: 5 },
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SkywalkerProtocol = void 0;
|
|
4
|
+
const shared_1 = require("../../shared");
|
|
5
|
+
const uuid_1 = require("uuid");
|
|
6
|
+
/**
|
|
7
|
+
* Skywalker Protocol - Real-time presence, typing, and reactions
|
|
8
|
+
*/
|
|
9
|
+
class SkywalkerProtocol {
|
|
10
|
+
constructor(client) {
|
|
11
|
+
this.skyDebug = (0, shared_1.debugChannel)('realtime', 'skywalker');
|
|
12
|
+
this.client = client;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Send typing indicator
|
|
16
|
+
*/
|
|
17
|
+
async sendTypingIndicator(threadId, isTyping = true) {
|
|
18
|
+
this.skyDebug(`${isTyping ? 'Starting' : 'Stopping'} typing in thread ${threadId}`);
|
|
19
|
+
const command = {
|
|
20
|
+
action: isTyping ? 'typing_on' : 'typing_off',
|
|
21
|
+
thread_id: threadId,
|
|
22
|
+
timestamp: Date.now(),
|
|
23
|
+
client_context: (0, uuid_1.v4)(),
|
|
24
|
+
};
|
|
25
|
+
return this.client.directCommands?.sendCommand({
|
|
26
|
+
action: 'send_typing',
|
|
27
|
+
data: command,
|
|
28
|
+
threadId,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Send message reaction
|
|
33
|
+
*/
|
|
34
|
+
async sendReaction(messageId, threadId, reactionEmoji) {
|
|
35
|
+
this.skyDebug(`Sending reaction ${reactionEmoji} to message ${messageId}`);
|
|
36
|
+
const command = {
|
|
37
|
+
action: 'reaction',
|
|
38
|
+
message_id: messageId,
|
|
39
|
+
thread_id: threadId,
|
|
40
|
+
emoji: reactionEmoji,
|
|
41
|
+
timestamp: Date.now(),
|
|
42
|
+
client_context: (0, uuid_1.v4)(),
|
|
43
|
+
};
|
|
44
|
+
return this.client.directCommands?.sendCommand({
|
|
45
|
+
action: 'send_reaction',
|
|
46
|
+
data: command,
|
|
47
|
+
threadId,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Handle Skywalker event
|
|
52
|
+
*/
|
|
53
|
+
handleSkywalkerEvent(data) {
|
|
54
|
+
try {
|
|
55
|
+
const event = typeof data === 'string' ? JSON.parse(data) : data;
|
|
56
|
+
this.skyDebug(`Skywalker Event: ${event.type || 'unknown'}`);
|
|
57
|
+
|
|
58
|
+
if (event.type === 'typing_on') {
|
|
59
|
+
this.client.emit('typing', {
|
|
60
|
+
user_id: event.from_user_id,
|
|
61
|
+
thread_id: event.thread_id,
|
|
62
|
+
is_typing: true,
|
|
63
|
+
});
|
|
64
|
+
} else if (event.type === 'typing_off') {
|
|
65
|
+
this.client.emit('typing', {
|
|
66
|
+
user_id: event.from_user_id,
|
|
67
|
+
thread_id: event.thread_id,
|
|
68
|
+
is_typing: false,
|
|
69
|
+
});
|
|
70
|
+
} else if (event.type === 'reaction') {
|
|
71
|
+
this.client.emit('reaction', {
|
|
72
|
+
message_id: event.message_id,
|
|
73
|
+
user_id: event.from_user_id,
|
|
74
|
+
emoji: event.emoji,
|
|
75
|
+
thread_id: event.thread_id,
|
|
76
|
+
});
|
|
77
|
+
} else if (event.type === 'presence') {
|
|
78
|
+
this.client.emit('presence', {
|
|
79
|
+
user_id: event.user_id,
|
|
80
|
+
status: event.status, // online, offline, away
|
|
81
|
+
last_activity: event.last_activity,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return event;
|
|
85
|
+
} catch (err) {
|
|
86
|
+
this.skyDebug(`Failed to parse Skywalker event: ${err.message}`);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.SkywalkerProtocol = SkywalkerProtocol;
|