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,280 @@
|
|
|
1
|
+
const crypto = require('crypto');
|
|
2
|
+
const { random } = require('lodash');
|
|
3
|
+
|
|
4
|
+
class Utils {
|
|
5
|
+
// ========================
|
|
6
|
+
// ORIGINAL FUNCTIONS
|
|
7
|
+
// ========================
|
|
8
|
+
|
|
9
|
+
static generateUUID() {
|
|
10
|
+
if (crypto.randomUUID) return crypto.randomUUID();
|
|
11
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
12
|
+
const r = Math.random() * 16 | 0;
|
|
13
|
+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
14
|
+
return v.toString(16);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static generateRandomString(length) {
|
|
19
|
+
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
20
|
+
let result = '';
|
|
21
|
+
for (let i = 0; i < length; i++) {
|
|
22
|
+
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static generateDeviceId() {
|
|
28
|
+
return 'android-' + this.generateRandomString(16);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static generatePhoneId() {
|
|
32
|
+
return this.generateUUID();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static generateAdId() {
|
|
36
|
+
return this.generateUUID();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static sleep(ms) {
|
|
40
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static randomDelay(min = 1000, max = 3000) {
|
|
44
|
+
return this.sleep(random(min, max));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static md5(data) {
|
|
48
|
+
return crypto.createHash('md5').update(data).digest('hex');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static sha256(data) {
|
|
52
|
+
return crypto.createHash('sha256').update(data).digest('hex');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static hmacSha256(data, key) {
|
|
56
|
+
return crypto.createHmac('sha256', key).update(data).digest('hex');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static base64Encode(data) {
|
|
60
|
+
return Buffer.from(data).toString('base64');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static base64Decode(data) {
|
|
64
|
+
return Buffer.from(data, 'base64').toString();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static getCurrentTimestamp() {
|
|
68
|
+
return Math.floor(Date.now() / 1000);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static getTimestampMs() {
|
|
72
|
+
return Date.now();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static formatUserAgent(appVersion, deviceString, language, appVersionCode) {
|
|
76
|
+
return `Instagram ${appVersion} Android (${deviceString}; ${language}; ${appVersionCode})`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static formatWebUserAgent(devicePayload, build, appUserAgent) {
|
|
80
|
+
return `Mozilla/5.0 (Linux; Android ${devicePayload.android_release}; ${devicePayload.model} Build/${build}; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36 ${appUserAgent}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static parseUserId(userIdOrUsername) {
|
|
84
|
+
if (typeof userIdOrUsername === 'number' || /^\d+$/.test(userIdOrUsername)) {
|
|
85
|
+
return userIdOrUsername.toString();
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static isValidEmail(email) {
|
|
91
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
92
|
+
return emailRegex.test(email);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static isValidUsername(username) {
|
|
96
|
+
const usernameRegex = /^[a-zA-Z0-9._]{1,30}$/;
|
|
97
|
+
return usernameRegex.test(username);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static sanitizeCaption(caption) {
|
|
101
|
+
if (!caption) return '';
|
|
102
|
+
return caption.replace(/[\u0000-\u001F\u007F-\u009F]/g, '');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static chunkArray(array, chunkSize) {
|
|
106
|
+
const chunks = [];
|
|
107
|
+
for (let i = 0; i < array.length; i += chunkSize) {
|
|
108
|
+
chunks.push(array.slice(i, i + chunkSize));
|
|
109
|
+
}
|
|
110
|
+
return chunks;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static retryOperation(operation, maxRetries = 3, delay = 1000) {
|
|
114
|
+
return new Promise((resolve, reject) => {
|
|
115
|
+
let retries = 0;
|
|
116
|
+
|
|
117
|
+
const attempt = async () => {
|
|
118
|
+
try {
|
|
119
|
+
const result = await operation();
|
|
120
|
+
resolve(result);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
retries++;
|
|
123
|
+
if (retries >= maxRetries) {
|
|
124
|
+
reject(error);
|
|
125
|
+
} else {
|
|
126
|
+
setTimeout(attempt, delay * retries);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
attempt();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static validateFileSize(filePath, maxSizeBytes) {
|
|
136
|
+
const fs = require('fs');
|
|
137
|
+
try {
|
|
138
|
+
const stats = fs.statSync(filePath);
|
|
139
|
+
return stats.size <= maxSizeBytes;
|
|
140
|
+
} catch (error) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static getFileExtension(filePath) {
|
|
146
|
+
return filePath.split('.').pop().toLowerCase();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static isImageFile(filePath) {
|
|
150
|
+
const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
|
|
151
|
+
const extension = this.getFileExtension(filePath);
|
|
152
|
+
return imageExtensions.includes(extension);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
static isVideoFile(filePath) {
|
|
156
|
+
const videoExtensions = ['mp4', 'mov', 'avi', 'mkv', 'webm', '3gp'];
|
|
157
|
+
const extension = this.getFileExtension(filePath);
|
|
158
|
+
return videoExtensions.includes(extension);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static humanizeError(error) {
|
|
162
|
+
const errorMessages = {
|
|
163
|
+
'IgLoginBadPasswordError': 'The password you entered is incorrect. Please check your password and try again.',
|
|
164
|
+
'IgLoginInvalidUserError': 'The username you entered doesn\'t appear to belong to an account. Please check your username and try again.',
|
|
165
|
+
'IgLoginTwoFactorRequiredError': 'Two-factor authentication is required. Please enter the verification code.',
|
|
166
|
+
'IgCheckpointError': 'Instagram requires additional verification. Please complete the security challenge.',
|
|
167
|
+
'IgActionSpamError': 'This action has been blocked by Instagram\'s spam detection. Please try again later.',
|
|
168
|
+
'IgNotFoundError': 'The requested content could not be found.',
|
|
169
|
+
'IgPrivateUserError': 'This account is private. You must follow this user to see their content.',
|
|
170
|
+
'IgUserHasLoggedOutError': 'Your session has expired. Please log in again.',
|
|
171
|
+
'IgInactiveUserError': 'This account is inactive or has been suspended.',
|
|
172
|
+
'IgSentryBlockError': 'This request has been blocked by Instagram\'s security system.',
|
|
173
|
+
'IgNetworkError': 'A network error occurred. Please check your internet connection and try again.',
|
|
174
|
+
'IgUploadError': 'Failed to upload the file. Please check the file format and size.',
|
|
175
|
+
'IgConfigureMediaError': 'Failed to configure the media. Please try again.',
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
if (error.response && error.response.status) {
|
|
179
|
+
return `Request failed with status ${error.response.status}: ${error.response.statusText || ''}`;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return errorMessages[error.name] || error.message || 'An unknown error occurred.';
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
static rateLimitDelay(retryAfter = null) {
|
|
186
|
+
if (retryAfter) {
|
|
187
|
+
return parseInt(retryAfter) * 1000;
|
|
188
|
+
}
|
|
189
|
+
return random(5000, 15000);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
static createUserAgentFromDevice(device) {
|
|
193
|
+
return `Instagram 401.0.0.48.79 Android (${device.android_version}/${device.android_release}; ${device.dpi}dpi; ${device.resolution}; ${device.manufacturer}; ${device.model}; ${device.device}; ${device.cpu})`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// ========================
|
|
197
|
+
// NEW ENHANCEMENTS
|
|
198
|
+
// ========================
|
|
199
|
+
|
|
200
|
+
static generateSecureRandomString(length) {
|
|
201
|
+
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
202
|
+
const randomBytes = crypto.randomBytes(length);
|
|
203
|
+
let result = '';
|
|
204
|
+
for (let i = 0; i < length; i++) {
|
|
205
|
+
result += characters[randomBytes[i] % characters.length];
|
|
206
|
+
}
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
static fileHash(filePath, algorithm = 'sha256') {
|
|
211
|
+
const fs = require('fs');
|
|
212
|
+
const data = fs.readFileSync(filePath);
|
|
213
|
+
return crypto.createHash(algorithm).update(data).digest('hex');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
static prettyBytes(bytes) {
|
|
217
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
218
|
+
let i = 0;
|
|
219
|
+
while (bytes >= 1024 && i < units.length - 1) {
|
|
220
|
+
bytes /= 1024;
|
|
221
|
+
i++;
|
|
222
|
+
}
|
|
223
|
+
return `${bytes.toFixed(2)} ${units[i]}`;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
static async retryWithBackoff(operation, maxRetries = 5, baseDelay = 1000) {
|
|
227
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
228
|
+
try {
|
|
229
|
+
return await operation();
|
|
230
|
+
} catch (error) {
|
|
231
|
+
if (attempt === maxRetries) throw error;
|
|
232
|
+
const delay = baseDelay * Math.pow(2, attempt - 1) + Math.random() * 500;
|
|
233
|
+
await this.sleep(delay);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
static logError(error, context = '') {
|
|
239
|
+
console.error(`[${new Date().toISOString()}] ā ${context}:`, {
|
|
240
|
+
name: error.name,
|
|
241
|
+
message: error.message,
|
|
242
|
+
stack: error.stack?.split('\n').slice(0, 3).join('\n')
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
static debugLog(message) {
|
|
247
|
+
if (process.env.DEBUG === 'true') {
|
|
248
|
+
console.log(`[DEBUG] ${new Date().toISOString()} - ${message}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
static generateAndroidDevice() {
|
|
253
|
+
const versions = ['11', '12', '13', '14'];
|
|
254
|
+
const models = ['Pixel 6', 'SM-G991B', 'Redmi Note 10', 'OnePlus 9'];
|
|
255
|
+
const manufacturer = ['Google', 'Samsung', 'Xiaomi', 'OnePlus'];
|
|
256
|
+
const randomIndex = Math.floor(Math.random() * models.length);
|
|
257
|
+
return {
|
|
258
|
+
android_release: versions[randomIndex],
|
|
259
|
+
model: models[randomIndex],
|
|
260
|
+
manufacturer: manufacturer[randomIndex],
|
|
261
|
+
dpi: 480,
|
|
262
|
+
resolution: '1080x2400',
|
|
263
|
+
device: models[randomIndex].replace(/\s+/g, '_').toLowerCase(),
|
|
264
|
+
cpu: 'arm64-v8a',
|
|
265
|
+
android_version: versions[randomIndex]
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
static generateHeaders(userAgent) {
|
|
270
|
+
return {
|
|
271
|
+
'User-Agent': userAgent,
|
|
272
|
+
'Accept': '*/*',
|
|
273
|
+
'Accept-Language': 'en-US',
|
|
274
|
+
'X-Requested-With': 'com.instagram.android',
|
|
275
|
+
'Connection': 'keep-alive'
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
module.exports = Utils;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const { IgApiClient, RealtimeClient } = require('../dist/index');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
// Listen to Instagram Direct Messages in Real-Time
|
|
6
|
+
// Setup: export INSTAGRAM_USERNAME, INSTAGRAM_PASSWORD, INSTAGRAM_EMAIL
|
|
7
|
+
// Run: node examples/listen-to-messages.js
|
|
8
|
+
|
|
9
|
+
async function main() {
|
|
10
|
+
const username = process.env.INSTAGRAM_USERNAME;
|
|
11
|
+
const password = process.env.INSTAGRAM_PASSWORD;
|
|
12
|
+
const email = process.env.INSTAGRAM_EMAIL;
|
|
13
|
+
|
|
14
|
+
if (!username || !password || !email) {
|
|
15
|
+
console.error('Missing credentials!');
|
|
16
|
+
console.error('Set: INSTAGRAM_USERNAME, INSTAGRAM_PASSWORD, INSTAGRAM_EMAIL');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
console.log('\nš± Instagram Direct Messages Listener\n');
|
|
22
|
+
|
|
23
|
+
const ig = new IgApiClient();
|
|
24
|
+
|
|
25
|
+
// Try to load saved session
|
|
26
|
+
const sessionFile = path.join(__dirname, '../.session');
|
|
27
|
+
if (fs.existsSync(sessionFile)) {
|
|
28
|
+
console.log('Loading saved session...');
|
|
29
|
+
const session = JSON.parse(fs.readFileSync(sessionFile, 'utf8'));
|
|
30
|
+
await ig.loadSession(session);
|
|
31
|
+
} else {
|
|
32
|
+
console.log('Logging in...');
|
|
33
|
+
await ig.login({ username, password, email });
|
|
34
|
+
const session = await ig.saveSession();
|
|
35
|
+
fs.writeFileSync(sessionFile, JSON.stringify(session));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log(`ā Logged in as @${username}\n`);
|
|
39
|
+
|
|
40
|
+
const realtime = new RealtimeClient(ig);
|
|
41
|
+
|
|
42
|
+
realtime.on('connected', () => {
|
|
43
|
+
console.log('ā Connected to MQTT\n');
|
|
44
|
+
console.log('Waiting for messages... (send a DM to yourself)\n');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
realtime.on('receive', (topic, messages) => {
|
|
48
|
+
if (Array.isArray(messages)) {
|
|
49
|
+
messages.forEach(msg => {
|
|
50
|
+
if (msg.body) {
|
|
51
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāā');
|
|
52
|
+
console.log(`From: ${msg.from_user_id}`);
|
|
53
|
+
console.log(`Message: ${msg.body}`);
|
|
54
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
55
|
+
}
|
|
56
|
+
if (msg.message_data?.body) {
|
|
57
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāā');
|
|
58
|
+
console.log(`From: ${msg.from_user_id}`);
|
|
59
|
+
console.log(`Message: ${msg.message_data.body}`);
|
|
60
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
realtime.on('error', (error) => {
|
|
67
|
+
console.error('ā Error:', error.message);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
console.log('Connecting to Instagram MQTT...');
|
|
71
|
+
|
|
72
|
+
await realtime.connect({
|
|
73
|
+
graphQlSubs: ['ig_sub_direct'],
|
|
74
|
+
irisData: null
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
console.log('Press Ctrl+C to stop\n');
|
|
78
|
+
await new Promise(() => {});
|
|
79
|
+
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error('Error:', error.message);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nodejs-insta-private-api-mqtt",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Complete Instagram MQTT protocol with FULL iOS + Android support. 33 device presets (21 iOS + 12 Android). iPhone 16/15/14/13/12, iPad Pro, Samsung, Pixel, Huawei. Real-time DM messaging, view-once media extraction, sub-500ms latency.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "node examples/listen-to-messages.js",
|
|
8
|
+
"start": "node examples/listen-to-messages.js",
|
|
9
|
+
"example": "node complete-example.js",
|
|
10
|
+
"listen": "node complete-example.js"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"instagram",
|
|
14
|
+
"api",
|
|
15
|
+
"private",
|
|
16
|
+
"client",
|
|
17
|
+
"dm",
|
|
18
|
+
"direct",
|
|
19
|
+
"messages",
|
|
20
|
+
"stories",
|
|
21
|
+
"upload",
|
|
22
|
+
"mqtt",
|
|
23
|
+
"realtime",
|
|
24
|
+
"notifications",
|
|
25
|
+
"bot",
|
|
26
|
+
"automation",
|
|
27
|
+
"bulk-messaging",
|
|
28
|
+
"session-persistence",
|
|
29
|
+
"message-management",
|
|
30
|
+
"view-once",
|
|
31
|
+
"disappearing-media",
|
|
32
|
+
"media-download",
|
|
33
|
+
"baileys",
|
|
34
|
+
"ios",
|
|
35
|
+
"iphone",
|
|
36
|
+
"ipad",
|
|
37
|
+
"android",
|
|
38
|
+
"device-emulation",
|
|
39
|
+
"iphone-16",
|
|
40
|
+
"iphone-15",
|
|
41
|
+
"samsung",
|
|
42
|
+
"pixel"
|
|
43
|
+
],
|
|
44
|
+
"author": "BorutoSrg",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"axios": "^1.6.0",
|
|
48
|
+
"chalk": "^5.6.2",
|
|
49
|
+
"chance": "^1.1.11",
|
|
50
|
+
"crypto": "^1.0.1",
|
|
51
|
+
"debug": "^4.3.4",
|
|
52
|
+
"eventemitter3": "^5.0.1",
|
|
53
|
+
"form-data": "^4.0.0",
|
|
54
|
+
"lodash": "^4.17.21",
|
|
55
|
+
"mqtts": "^1.5.0",
|
|
56
|
+
"node-persist": "^4.0.4",
|
|
57
|
+
"pako": "^2.1.0",
|
|
58
|
+
"protobufjs": "^7.5.4",
|
|
59
|
+
"socks": "^2.8.1",
|
|
60
|
+
"tough-cookie": "^4.1.3",
|
|
61
|
+
"ts-custom-error": "^3.3.1",
|
|
62
|
+
"uuid": "^9.0.1"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"node-fetch": "^3.3.2",
|
|
66
|
+
"typescript": "^5.9.3"
|
|
67
|
+
},
|
|
68
|
+
"engines": {
|
|
69
|
+
"node": ">=18.0.0"
|
|
70
|
+
},
|
|
71
|
+
"repository": {
|
|
72
|
+
"type": "git",
|
|
73
|
+
"url": "https://github.com/Kunboruto20/nodejs-insta-private-api.git"
|
|
74
|
+
},
|
|
75
|
+
"bugs": {
|
|
76
|
+
"url": "https://github.com/Kunboruto20/nodejs-insta-private-api/issues"
|
|
77
|
+
},
|
|
78
|
+
"homepage": "https://github.com/Kunboruto20/nodejs-insta-private-api#readme"
|
|
79
|
+
}
|