nodejs-insta-private-api-mqt 1.3.70
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/LICENSE +21 -0
- package/README.md +3677 -0
- package/dist/constants/constants.js +342 -0
- package/dist/constants/index.js +58 -0
- package/dist/core/client.js +419 -0
- package/dist/core/nav-chain.js +282 -0
- package/dist/core/repository.js +7 -0
- package/dist/core/request.js +390 -0
- package/dist/core/state.js +1473 -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 +38 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/extend.js +167 -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 +252 -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 +139 -0
- package/dist/mqtt-shim.d.ts +96 -0
- package/dist/mqtt-shim.js +15 -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 +318 -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 +79 -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 +71 -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 +417 -0
- package/dist/realtime/commands/direct.commands.js.map +1 -0
- package/dist/realtime/commands/enhanced.direct.commands.js +1731 -0
- package/dist/realtime/commands/enhanced.direct.commands.js.bak +967 -0
- package/dist/realtime/commands/index.d.ts +2 -0
- package/dist/realtime/commands/index.js +20 -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 +185 -0
- package/dist/realtime/features/gap-handler.js +61 -0
- package/dist/realtime/features/persistent-logger.js +186 -0
- package/dist/realtime/features/presence.manager.js +66 -0
- package/dist/realtime/features/session-health-monitor.js +345 -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 +596 -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 +181 -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 +1915 -0
- package/dist/realtime/realtime.service.js +462 -0
- package/dist/realtime/reconnect.manager.js +88 -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 +575 -0
- package/dist/repositories/bloks.repository.js +70 -0
- package/dist/repositories/captcha.repository.js +44 -0
- package/dist/repositories/challenge.repository.js +120 -0
- package/dist/repositories/clip.repository.js +165 -0
- package/dist/repositories/close-friends.repository.js +46 -0
- package/dist/repositories/collection.repository.js +68 -0
- package/dist/repositories/direct-thread.repository.js +446 -0
- package/dist/repositories/direct.repository.js +232 -0
- package/dist/repositories/explore.repository.js +70 -0
- package/dist/repositories/fbsearch.repository.js +140 -0
- package/dist/repositories/feed.repository.js +245 -0
- package/dist/repositories/friendship.repository.js +296 -0
- package/dist/repositories/fundraiser.repository.js +49 -0
- package/dist/repositories/hashtag.repository.js +99 -0
- package/dist/repositories/highlights.repository.js +121 -0
- package/dist/repositories/insights.repository.js +82 -0
- package/dist/repositories/location.repository.js +84 -0
- package/dist/repositories/media.repository.js +395 -0
- package/dist/repositories/multiple-accounts.repository.js +41 -0
- package/dist/repositories/news.repository.js +35 -0
- package/dist/repositories/note.repository.js +57 -0
- package/dist/repositories/notification.repository.js +79 -0
- package/dist/repositories/share.repository.js +35 -0
- package/dist/repositories/signup.repository.js +218 -0
- package/dist/repositories/story.repository.js +290 -0
- package/dist/repositories/timeline.repository.js +60 -0
- package/dist/repositories/totp.repository.js +139 -0
- package/dist/repositories/track.repository.js +53 -0
- package/dist/repositories/upload.repository.js +204 -0
- package/dist/repositories/user.repository.js +360 -0
- package/dist/sendmedia/index.js +27 -0
- package/dist/sendmedia/sendFile.js +72 -0
- package/dist/sendmedia/sendPhoto.js +142 -0
- package/dist/sendmedia/sendRavenPhoto.js +153 -0
- package/dist/sendmedia/sendRavenVideo.js +158 -0
- package/dist/sendmedia/uploadPhoto.js +107 -0
- package/dist/sendmedia/uploadfFile.js +130 -0
- package/dist/services/live.service.js +139 -0
- package/dist/services/search.service.js +115 -0
- package/dist/shared/index.js +96 -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 +1768 -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/dist/utils/insta-mqtt-helper.js +128 -0
- package/examples/listen-to-messages.js +86 -0
- package/package.json +82 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
const Repository = require('../core/repository');
|
|
2
|
+
|
|
3
|
+
const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
|
4
|
+
|
|
5
|
+
class UserRepository extends Repository {
|
|
6
|
+
constructor(client) {
|
|
7
|
+
super(client);
|
|
8
|
+
this._usersCache = {};
|
|
9
|
+
this._usernamesCache = {};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async infoByUsername(username) {
|
|
13
|
+
const response = await this.client.request.send({
|
|
14
|
+
method: 'GET',
|
|
15
|
+
url: `/api/v1/users/${username}/usernameinfo/`,
|
|
16
|
+
});
|
|
17
|
+
return response.body.user;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async info(userId) {
|
|
21
|
+
const response = await this.client.request.send({
|
|
22
|
+
method: 'GET',
|
|
23
|
+
url: `/api/v1/users/${userId}/info/`,
|
|
24
|
+
});
|
|
25
|
+
return response.body.user;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async infoV1(userId, fromModule = 'self_profile') {
|
|
29
|
+
const response = await this.client.request.send({
|
|
30
|
+
method: 'GET',
|
|
31
|
+
url: `/api/v1/users/${userId}/info/`,
|
|
32
|
+
qs: { from_module: fromModule },
|
|
33
|
+
});
|
|
34
|
+
return response.body.user;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async userIdFromUsername(username) {
|
|
38
|
+
const user = await this.infoByUsername(username.toLowerCase());
|
|
39
|
+
return String(user.pk);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async usernameFromUserId(userId) {
|
|
43
|
+
const user = await this.info(userId);
|
|
44
|
+
return user.username;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async search(query, count = 50) {
|
|
48
|
+
const response = await this.client.request.send({
|
|
49
|
+
method: 'GET',
|
|
50
|
+
url: '/api/v1/users/search/',
|
|
51
|
+
qs: { q: query, count },
|
|
52
|
+
});
|
|
53
|
+
return response.body.users;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async searchExact(username) {
|
|
57
|
+
const response = await this.client.request.send({
|
|
58
|
+
method: 'GET',
|
|
59
|
+
url: '/api/v1/users/search/',
|
|
60
|
+
qs: {
|
|
61
|
+
q: username,
|
|
62
|
+
count: 1,
|
|
63
|
+
search_surface: 'user_search_page',
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
const users = response.body.users || [];
|
|
67
|
+
return users.find(u => u.username === username) || null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async follow(userId) {
|
|
71
|
+
const response = await this.client.request.send({
|
|
72
|
+
method: 'POST',
|
|
73
|
+
url: `/api/v1/friendships/create/${userId}/`,
|
|
74
|
+
form: this.client.request.sign({
|
|
75
|
+
_uid: this.client.state.cookieUserId,
|
|
76
|
+
_uuid: this.client.state.uuid,
|
|
77
|
+
user_id: userId,
|
|
78
|
+
}),
|
|
79
|
+
});
|
|
80
|
+
return response.body;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async unfollow(userId) {
|
|
84
|
+
const response = await this.client.request.send({
|
|
85
|
+
method: 'POST',
|
|
86
|
+
url: `/api/v1/friendships/destroy/${userId}/`,
|
|
87
|
+
form: this.client.request.sign({
|
|
88
|
+
_uid: this.client.state.cookieUserId,
|
|
89
|
+
_uuid: this.client.state.uuid,
|
|
90
|
+
user_id: userId,
|
|
91
|
+
}),
|
|
92
|
+
});
|
|
93
|
+
return response.body;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async getFollowers(userId, amount = 200, maxId = null) {
|
|
97
|
+
return this._paginateUsers(`/api/v1/friendships/${userId}/followers/`, amount, maxId);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async getFollowing(userId, amount = 200, maxId = null) {
|
|
101
|
+
return this._paginateUsers(`/api/v1/friendships/${userId}/following/`, amount, maxId);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async _paginateUsers(endpoint, amount = 200, startMaxId = null) {
|
|
105
|
+
const allUsers = [];
|
|
106
|
+
let nextMaxId = startMaxId;
|
|
107
|
+
while (allUsers.length < amount) {
|
|
108
|
+
const qs = {};
|
|
109
|
+
if (nextMaxId) qs.max_id = nextMaxId;
|
|
110
|
+
const response = await this.client.request.send({
|
|
111
|
+
method: 'GET',
|
|
112
|
+
url: endpoint,
|
|
113
|
+
qs,
|
|
114
|
+
});
|
|
115
|
+
const body = response.body;
|
|
116
|
+
const users = body.users || [];
|
|
117
|
+
allUsers.push(...users);
|
|
118
|
+
if (!body.next_max_id) break;
|
|
119
|
+
nextMaxId = body.next_max_id;
|
|
120
|
+
}
|
|
121
|
+
return { users: allUsers.slice(0, amount), nextMaxId };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async getFriendshipStatuses(userIds) {
|
|
125
|
+
const response = await this.client.request.send({
|
|
126
|
+
method: 'POST',
|
|
127
|
+
url: '/api/v1/friendships/show_many/',
|
|
128
|
+
form: this.client.request.sign({
|
|
129
|
+
user_ids: Array.isArray(userIds) ? userIds.join(',') : userIds,
|
|
130
|
+
_uuid: this.client.state.uuid,
|
|
131
|
+
}),
|
|
132
|
+
});
|
|
133
|
+
return response.body;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async friendshipShow(userId) {
|
|
137
|
+
const response = await this.client.request.send({
|
|
138
|
+
method: 'GET',
|
|
139
|
+
url: `/api/v1/friendships/show/${userId}/`,
|
|
140
|
+
});
|
|
141
|
+
return response.body;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async getReelsTrayFeed() {
|
|
145
|
+
const response = await this.client.request.send({
|
|
146
|
+
method: 'GET',
|
|
147
|
+
url: '/api/v1/feed/reels_tray/',
|
|
148
|
+
});
|
|
149
|
+
return response.body;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async getUserTags(userId, maxId = null) {
|
|
153
|
+
const qs = {};
|
|
154
|
+
if (maxId) qs.max_id = maxId;
|
|
155
|
+
const response = await this.client.request.send({
|
|
156
|
+
method: 'GET',
|
|
157
|
+
url: `/api/v1/usertags/${userId}/feed/`,
|
|
158
|
+
qs,
|
|
159
|
+
});
|
|
160
|
+
return response.body;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async getUserMedias(userId, amount = 50, maxId = null) {
|
|
164
|
+
const allItems = [];
|
|
165
|
+
let nextMaxId = maxId;
|
|
166
|
+
while (allItems.length < amount) {
|
|
167
|
+
const qs = { count: Math.min(amount - allItems.length, 33) };
|
|
168
|
+
if (nextMaxId) qs.max_id = nextMaxId;
|
|
169
|
+
const response = await this.client.request.send({
|
|
170
|
+
method: 'GET',
|
|
171
|
+
url: `/api/v1/feed/user/${userId}/`,
|
|
172
|
+
qs,
|
|
173
|
+
});
|
|
174
|
+
const body = response.body;
|
|
175
|
+
allItems.push(...(body.items || []));
|
|
176
|
+
if (!body.more_available || !body.next_max_id) break;
|
|
177
|
+
nextMaxId = body.next_max_id;
|
|
178
|
+
}
|
|
179
|
+
return allItems.slice(0, amount);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async getUserReels(userId, amount = 50, maxId = null) {
|
|
183
|
+
const allItems = [];
|
|
184
|
+
let nextMaxId = maxId;
|
|
185
|
+
while (allItems.length < amount) {
|
|
186
|
+
const response = await this.client.request.send({
|
|
187
|
+
method: 'POST',
|
|
188
|
+
url: '/api/v1/clips/user/',
|
|
189
|
+
form: {
|
|
190
|
+
target_user_id: userId,
|
|
191
|
+
page_size: Math.min(amount - allItems.length, 12),
|
|
192
|
+
max_id: nextMaxId || '',
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
const body = response.body;
|
|
196
|
+
for (const item of (body.items || [])) {
|
|
197
|
+
allItems.push(item.media || item);
|
|
198
|
+
}
|
|
199
|
+
const pagingInfo = body.paging_info || {};
|
|
200
|
+
if (!pagingInfo.more_available) break;
|
|
201
|
+
nextMaxId = pagingInfo.max_id || '';
|
|
202
|
+
}
|
|
203
|
+
return allItems.slice(0, amount);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async getUserClips(userId, amount = 50, maxId = null) {
|
|
207
|
+
return this.getUserReels(userId, amount, maxId);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async getUserStories(userId) {
|
|
211
|
+
const response = await this.client.request.send({
|
|
212
|
+
method: 'POST',
|
|
213
|
+
url: `/api/v1/feed/user/${userId}/story/`,
|
|
214
|
+
form: {
|
|
215
|
+
supported_capabilities_new: JSON.stringify(this.client.state.constants.SUPPORTED_CAPABILITIES),
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
return response.body;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async setSelfBio(biography) {
|
|
222
|
+
const response = await this.client.request.send({
|
|
223
|
+
method: 'POST',
|
|
224
|
+
url: '/api/v1/accounts/set_biography/',
|
|
225
|
+
form: this.client.request.sign({
|
|
226
|
+
_uid: this.client.state.cookieUserId,
|
|
227
|
+
_uuid: this.client.state.uuid,
|
|
228
|
+
raw_text: biography,
|
|
229
|
+
}),
|
|
230
|
+
});
|
|
231
|
+
return response.body;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async report(userId, reason = 1) {
|
|
235
|
+
const response = await this.client.request.send({
|
|
236
|
+
method: 'POST',
|
|
237
|
+
url: `/api/v1/users/${userId}/flag_user/`,
|
|
238
|
+
form: this.client.request.sign({
|
|
239
|
+
reason_id: reason,
|
|
240
|
+
_uid: this.client.state.cookieUserId,
|
|
241
|
+
_uuid: this.client.state.uuid,
|
|
242
|
+
}),
|
|
243
|
+
});
|
|
244
|
+
return response.body;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
async getSuggested() {
|
|
248
|
+
const response = await this.client.request.send({
|
|
249
|
+
method: 'GET',
|
|
250
|
+
url: '/api/v1/discover/ayml/',
|
|
251
|
+
});
|
|
252
|
+
return response.body;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
async block(userId) {
|
|
256
|
+
const response = await this.client.request.send({
|
|
257
|
+
method: 'POST',
|
|
258
|
+
url: `/api/v1/friendships/block/${userId}/`,
|
|
259
|
+
form: this.client.request.sign({
|
|
260
|
+
_uid: this.client.state.cookieUserId,
|
|
261
|
+
_uuid: this.client.state.uuid,
|
|
262
|
+
user_id: userId,
|
|
263
|
+
}),
|
|
264
|
+
});
|
|
265
|
+
return response.body;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async unblock(userId) {
|
|
269
|
+
const response = await this.client.request.send({
|
|
270
|
+
method: 'POST',
|
|
271
|
+
url: `/api/v1/friendships/unblock/${userId}/`,
|
|
272
|
+
form: this.client.request.sign({
|
|
273
|
+
_uid: this.client.state.cookieUserId,
|
|
274
|
+
_uuid: this.client.state.uuid,
|
|
275
|
+
user_id: userId,
|
|
276
|
+
}),
|
|
277
|
+
});
|
|
278
|
+
return response.body;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async mute(userId, { muteStories = false, mutePosts = false } = {}) {
|
|
282
|
+
const response = await this.client.request.send({
|
|
283
|
+
method: 'POST',
|
|
284
|
+
url: `/api/v1/friendships/mute_posts_or_story_from_follow/`,
|
|
285
|
+
form: this.client.request.sign({
|
|
286
|
+
_uid: this.client.state.cookieUserId,
|
|
287
|
+
_uuid: this.client.state.uuid,
|
|
288
|
+
target_posts_author_id: mutePosts ? userId : '',
|
|
289
|
+
target_reel_author_id: muteStories ? userId : '',
|
|
290
|
+
}),
|
|
291
|
+
});
|
|
292
|
+
return response.body;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async unmute(userId, { unmuteStories = false, unmutePosts = false } = {}) {
|
|
296
|
+
const response = await this.client.request.send({
|
|
297
|
+
method: 'POST',
|
|
298
|
+
url: `/api/v1/friendships/unmute_posts_or_story_from_follow/`,
|
|
299
|
+
form: this.client.request.sign({
|
|
300
|
+
_uid: this.client.state.cookieUserId,
|
|
301
|
+
_uuid: this.client.state.uuid,
|
|
302
|
+
target_posts_author_id: unmutePosts ? userId : '',
|
|
303
|
+
target_reel_author_id: unmuteStories ? userId : '',
|
|
304
|
+
}),
|
|
305
|
+
});
|
|
306
|
+
return response.body;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async removeFollower(userId) {
|
|
310
|
+
const response = await this.client.request.send({
|
|
311
|
+
method: 'POST',
|
|
312
|
+
url: `/api/v1/friendships/remove_follower/${userId}/`,
|
|
313
|
+
form: this.client.request.sign({
|
|
314
|
+
_uid: this.client.state.cookieUserId,
|
|
315
|
+
_uuid: this.client.state.uuid,
|
|
316
|
+
user_id: userId,
|
|
317
|
+
}),
|
|
318
|
+
});
|
|
319
|
+
return response.body;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
async getBlockedUsers() {
|
|
323
|
+
const response = await this.client.request.send({
|
|
324
|
+
method: 'GET',
|
|
325
|
+
url: '/api/v1/users/blocked_list/',
|
|
326
|
+
});
|
|
327
|
+
return response.body;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async getMutualFollowers(userId) {
|
|
331
|
+
const response = await this.client.request.send({
|
|
332
|
+
method: 'GET',
|
|
333
|
+
url: `/api/v1/friendships/${userId}/mutual_followers/`,
|
|
334
|
+
});
|
|
335
|
+
return response.body;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
static mediaPkFromCode(code) {
|
|
339
|
+
let pk = BigInt(0);
|
|
340
|
+
for (let i = 0; i < code.length; i++) {
|
|
341
|
+
const idx = ALPHABET.indexOf(code[i]);
|
|
342
|
+
if (idx === -1) continue;
|
|
343
|
+
pk = pk * BigInt(64) + BigInt(idx);
|
|
344
|
+
}
|
|
345
|
+
return pk.toString();
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
static mediaCodeFromPk(pk) {
|
|
349
|
+
let id = BigInt(pk);
|
|
350
|
+
let code = '';
|
|
351
|
+
while (id > BigInt(0)) {
|
|
352
|
+
const remainder = Number(id % BigInt(64));
|
|
353
|
+
code = ALPHABET[remainder] + code;
|
|
354
|
+
id = id / BigInt(64);
|
|
355
|
+
}
|
|
356
|
+
return code;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
module.exports = UserRepository;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const sendPhoto = require('./sendPhoto');
|
|
2
|
+
const sendFile = require('./sendFile');
|
|
3
|
+
const uploadPhoto = require('./uploadPhoto');
|
|
4
|
+
const uploadFile = require('./uploadfFile');
|
|
5
|
+
const sendRavenPhotoModule = require('./sendRavenPhoto');
|
|
6
|
+
const sendRavenVideoModule = require('./sendRavenVideo');
|
|
7
|
+
|
|
8
|
+
const sendRavenPhoto = sendRavenPhotoModule.sendRavenPhoto || sendRavenPhotoModule;
|
|
9
|
+
const sendRavenPhotoOnce = sendRavenPhotoModule.sendRavenPhotoOnce;
|
|
10
|
+
const sendRavenPhotoReplayable = sendRavenPhotoModule.sendRavenPhotoReplayable;
|
|
11
|
+
|
|
12
|
+
const sendRavenVideo = sendRavenVideoModule.sendRavenVideo || sendRavenVideoModule;
|
|
13
|
+
const sendRavenVideoOnce = sendRavenVideoModule.sendRavenVideoOnce;
|
|
14
|
+
const sendRavenVideoReplayable = sendRavenVideoModule.sendRavenVideoReplayable;
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
sendPhoto,
|
|
18
|
+
sendFile,
|
|
19
|
+
uploadPhoto,
|
|
20
|
+
uploadFile,
|
|
21
|
+
sendRavenPhoto,
|
|
22
|
+
sendRavenPhotoOnce,
|
|
23
|
+
sendRavenPhotoReplayable,
|
|
24
|
+
sendRavenVideo,
|
|
25
|
+
sendRavenVideoOnce,
|
|
26
|
+
sendRavenVideoReplayable,
|
|
27
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sendFile.js - Fixed to support MQTT if realtime client provided
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const uploadFile = require('./uploadfFile');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Send a file to Instagram Direct.
|
|
9
|
+
*/
|
|
10
|
+
async function sendFile(session, opts = {}) {
|
|
11
|
+
const {
|
|
12
|
+
fileBuffer,
|
|
13
|
+
mimeType = 'video/mp4',
|
|
14
|
+
fileName,
|
|
15
|
+
caption = '',
|
|
16
|
+
userId,
|
|
17
|
+
threadId,
|
|
18
|
+
signal,
|
|
19
|
+
realtimeClient,
|
|
20
|
+
} = opts;
|
|
21
|
+
|
|
22
|
+
if (!userId && !threadId) {
|
|
23
|
+
throw new Error('sendFile: Provide userId or threadId.');
|
|
24
|
+
}
|
|
25
|
+
if (!fileBuffer || !Buffer.isBuffer(fileBuffer) || fileBuffer.length === 0) {
|
|
26
|
+
throw new Error('sendFile: fileBuffer must be a non-empty Buffer.');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 1) Upload
|
|
30
|
+
const upload_id = await uploadFile(session, fileBuffer, {
|
|
31
|
+
mimeType,
|
|
32
|
+
fileName,
|
|
33
|
+
signal,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// 2) MQTT Check
|
|
37
|
+
if (realtimeClient && realtimeClient.direct && typeof realtimeClient.direct.sendMedia === 'function') {
|
|
38
|
+
return await realtimeClient.direct.sendMedia({
|
|
39
|
+
text: caption,
|
|
40
|
+
mediaId: upload_id,
|
|
41
|
+
threadId: threadId || userId,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 3) REST Fallback
|
|
46
|
+
const url = '/direct_v2/threads/broadcast/upload_video/';
|
|
47
|
+
const form = {
|
|
48
|
+
upload_id,
|
|
49
|
+
action: 'send_item',
|
|
50
|
+
caption,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
if (userId) {
|
|
54
|
+
form.recipient_users = JSON.stringify([[String(userId)]]);
|
|
55
|
+
} else {
|
|
56
|
+
form.thread_ids = JSON.stringify([String(threadId)]);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const response = await session.request.send({
|
|
61
|
+
url,
|
|
62
|
+
method: 'POST',
|
|
63
|
+
form,
|
|
64
|
+
signal,
|
|
65
|
+
});
|
|
66
|
+
return response;
|
|
67
|
+
} catch (err) {
|
|
68
|
+
throw new Error(`sendFile: Broadcast failed — ${err.message}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = sendFile;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uploadPhoto.fixed.js
|
|
3
|
+
*
|
|
4
|
+
* Fixed and hardened version of uploadPhoto for nodejs-insta-private-api(-mqtt).
|
|
5
|
+
* - sends Buffer in `data` (axios uses `data`, not `body`)
|
|
6
|
+
* - sets axios-friendly headers (X-Entity-Type uses provided mimeType)
|
|
7
|
+
* - removes explicit Accept-Encoding header (axios handles it)
|
|
8
|
+
* - sets maxContentLength / maxBodyLength via Request httpClient (should be patched there too)
|
|
9
|
+
* - returns the rupload/uploadId (server-provided when available, otherwise local uploadId)
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* const uploadPhoto = require('./uploadPhoto.fixed');
|
|
13
|
+
* const uploadId = await uploadPhoto(session, photoBuffer, { mimeType: 'image/jpeg' });
|
|
14
|
+
*
|
|
15
|
+
* Note: session.request.send(...) is expected to accept axios-like options.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const { v4: uuidv4 } = require('uuid');
|
|
19
|
+
|
|
20
|
+
function validateImageInput(photoBuffer, mimeType) {
|
|
21
|
+
if (!photoBuffer || !Buffer.isBuffer(photoBuffer) || photoBuffer.length === 0) {
|
|
22
|
+
throw new Error('uploadPhoto: photoBuffer must be a non-empty Buffer.');
|
|
23
|
+
}
|
|
24
|
+
const allowed = ['image/jpeg', 'image/jpg', 'image/png'];
|
|
25
|
+
if (!allowed.includes(mimeType)) {
|
|
26
|
+
throw new Error(`uploadPhoto: mimeType must be one of ${allowed.join(', ')}.`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function buildRuploadParams(uploadId, mimeType) {
|
|
31
|
+
const isJpeg = mimeType === 'image/jpeg' || mimeType === 'image/jpg';
|
|
32
|
+
const compression = isJpeg
|
|
33
|
+
? { lib_name: 'moz', lib_version: '3.1.m', quality: '80' }
|
|
34
|
+
: { lib_name: 'png', lib_version: '1.0', quality: '100' };
|
|
35
|
+
|
|
36
|
+
// Match instagram-private-api shape; include is_sidecar for compatibility
|
|
37
|
+
return {
|
|
38
|
+
retry_context: JSON.stringify({ num_step_auto_retry: 0, num_reupload: 0, num_step_manual_retry: 0 }),
|
|
39
|
+
media_type: '1',
|
|
40
|
+
upload_id: uploadId.toString(),
|
|
41
|
+
xsharing_user_ids: JSON.stringify([]),
|
|
42
|
+
image_compression: JSON.stringify(compression),
|
|
43
|
+
is_sidecar: '0'
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Upload a photo buffer to Instagram rupload endpoint.
|
|
49
|
+
*
|
|
50
|
+
* @param {Object} session - client/session object that exposes session.request.send(options)
|
|
51
|
+
* @param {Buffer} photoBuffer - binary buffer of the image
|
|
52
|
+
* @param {Object} options - { mimeType = 'image/jpeg', fileName?, signal? }
|
|
53
|
+
* @returns {Promise<string>} uploadId (server upload_id when available, otherwise local uploadId)
|
|
54
|
+
*/
|
|
55
|
+
async function uploadPhoto(session, photoBuffer, options = {}) {
|
|
56
|
+
const {
|
|
57
|
+
mimeType = 'image/jpeg',
|
|
58
|
+
fileName,
|
|
59
|
+
signal
|
|
60
|
+
} = options;
|
|
61
|
+
|
|
62
|
+
validateImageInput(photoBuffer, mimeType);
|
|
63
|
+
|
|
64
|
+
// local upload id similar to insta clients
|
|
65
|
+
const uploadId = Date.now().toString();
|
|
66
|
+
// create an entity name similar to instagram-private-api naming
|
|
67
|
+
const randomSuffix = Math.floor(Math.random() * (9999999999 - 1000000000) + 1000000000);
|
|
68
|
+
const name = `${uploadId}_0_${randomSuffix}`;
|
|
69
|
+
const contentLength = photoBuffer.byteLength;
|
|
70
|
+
|
|
71
|
+
const ruploadParams = buildRuploadParams(uploadId, mimeType);
|
|
72
|
+
|
|
73
|
+
const headers = {
|
|
74
|
+
'X_FB_PHOTO_WATERFALL_ID': uuidv4(),
|
|
75
|
+
'X-Entity-Type': mimeType, // use actual mimeType
|
|
76
|
+
'Offset': '0',
|
|
77
|
+
'X-Instagram-Rupload-Params': JSON.stringify(ruploadParams),
|
|
78
|
+
'X-Entity-Name': name,
|
|
79
|
+
'X-Entity-Length': String(contentLength),
|
|
80
|
+
'Content-Type': 'application/octet-stream',
|
|
81
|
+
'Content-Length': String(contentLength),
|
|
82
|
+
// remove explicit Accept-Encoding to avoid conflicts; axios handles compression
|
|
83
|
+
// 'Accept-Encoding': 'gzip',
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const url = `/rupload_igphoto/${name}`;
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
// session.request.send is expected to forward options to axios (or similar)
|
|
90
|
+
// We MUST use `data` (not `body`) for axios-friendly request.
|
|
91
|
+
const response = await session.request.send({
|
|
92
|
+
url,
|
|
93
|
+
method: 'POST',
|
|
94
|
+
headers,
|
|
95
|
+
data: photoBuffer,
|
|
96
|
+
signal,
|
|
97
|
+
// ensure axios does not apply any transform that would corrupt binary
|
|
98
|
+
transformRequest: [(d) => d]
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
if (!response) {
|
|
102
|
+
throw new Error('uploadPhoto: Empty response from Instagram rupload endpoint.');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// The request wrapper in different forks may return { body, headers } OR axios response
|
|
106
|
+
// Normalize possible shapes:
|
|
107
|
+
let respBody = null;
|
|
108
|
+
if (response.body !== undefined) {
|
|
109
|
+
// wrapper returned { body, headers }
|
|
110
|
+
respBody = response.body;
|
|
111
|
+
} else if (response.data !== undefined) {
|
|
112
|
+
respBody = response.data;
|
|
113
|
+
} else {
|
|
114
|
+
respBody = response;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// If respBody is a string, try parse JSON
|
|
118
|
+
let parsed = null;
|
|
119
|
+
if (typeof respBody === 'string') {
|
|
120
|
+
try { parsed = JSON.parse(respBody); } catch (e) { parsed = null; }
|
|
121
|
+
} else if (typeof respBody === 'object') {
|
|
122
|
+
parsed = respBody;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// server might return upload_id inside parsed
|
|
126
|
+
const serverUploadId = parsed && (parsed.upload_id || parsed.uploadId || parsed.media && parsed.media.upload_id);
|
|
127
|
+
if (serverUploadId) {
|
|
128
|
+
return serverUploadId.toString();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// fallback: some endpoints respond with status only; return our local uploadId
|
|
132
|
+
return uploadId;
|
|
133
|
+
} catch (err) {
|
|
134
|
+
// try to unwrap axios error message
|
|
135
|
+
let msg = '';
|
|
136
|
+
if (err && err.message) msg = err.message;
|
|
137
|
+
else msg = String(err);
|
|
138
|
+
throw new Error(`uploadPhoto: Upload failed — ${msg}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
module.exports = uploadPhoto;
|