instauto 9.1.2 → 9.1.3
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 +1 -1
- package/package.json +1 -1
- package/src/index.js +16 -38
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Now there is a GUI application for those who don't want to code: [SimpleInstaBot
|
|
|
25
25
|
|
|
26
26
|
You can run this code for example once every day using cron or pm2 or similar
|
|
27
27
|
|
|
28
|
-
See [index.js](https://github.com/mifi/instauto/blob/master/index.js) for available options.
|
|
28
|
+
See [index.js](https://github.com/mifi/instauto/blob/master/src/index.js) for available options.
|
|
29
29
|
|
|
30
30
|
## Supported functionality
|
|
31
31
|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -73,7 +73,6 @@ const Instauto = async (db, browser, options) => {
|
|
|
73
73
|
|
|
74
74
|
// State
|
|
75
75
|
let page;
|
|
76
|
-
let graphqlUserMissing = false;
|
|
77
76
|
|
|
78
77
|
async function takeScreenshot() {
|
|
79
78
|
if (!screenshotOnError) return;
|
|
@@ -221,37 +220,17 @@ const Instauto = async (db, browser, options) => {
|
|
|
221
220
|
}
|
|
222
221
|
|
|
223
222
|
async function navigateToUserAndGetData(username) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
await navigateToUserWithCheck(username);
|
|
236
|
-
return user;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
await navigateToUserWithCheck(username);
|
|
240
|
-
|
|
241
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
242
|
-
const sharedData = await page.evaluate(() => window._sharedData);
|
|
243
|
-
try {
|
|
244
|
-
// eslint-disable-next-line prefer-destructuring
|
|
245
|
-
return sharedData.entry_data.ProfilePage[0].graphql.user;
|
|
246
|
-
|
|
247
|
-
// JSON.parse(Array.from(document.getElementsByTagName('script')).find(el => el.innerHTML.startsWith('window.__additionalDataLoaded(\'feed\',')).innerHTML.replace(/^window.__additionalDataLoaded\('feed',({.*})\);$/, '$1'));
|
|
248
|
-
// JSON.parse(Array.from(document.getElementsByTagName('script')).find(el => el.innerHTML.startsWith('window._sharedData')).innerHTML.replace(/^window._sharedData ?= ?({.*});$/, '$1'));
|
|
249
|
-
// Array.from(document.getElementsByTagName('a')).find(el => el.attributes?.href?.value.includes(`${username}/followers`)).innerText
|
|
250
|
-
} catch (err) {
|
|
251
|
-
logger.warn('Missing graphql in page, falling back to alternative method...');
|
|
252
|
-
graphqlUserMissing = true; // Store as state so we don't have to do this every time from now on.
|
|
253
|
-
return navigateToUserAndGetData(username); // Now try again with alternative method
|
|
254
|
-
}
|
|
223
|
+
const [foundResponse] = await Promise.all([
|
|
224
|
+
page.waitForResponse((response) => {
|
|
225
|
+
const request = response.request();
|
|
226
|
+
return request.method() === 'GET' && new RegExp(`https:\\/\\/i\\.instagram\\.com\\/api\\/v1\\/users\\/web_profile_info\\/\\?username=${encodeURIComponent(username.toLowerCase())}`).test(request.url());
|
|
227
|
+
}),
|
|
228
|
+
navigateToUserWithCheck(username),
|
|
229
|
+
// page.waitForNavigation({ waitUntil: 'networkidle0' }),
|
|
230
|
+
]);
|
|
231
|
+
|
|
232
|
+
const json = JSON.parse(await foundResponse.text());
|
|
233
|
+
return json.data.user;
|
|
255
234
|
}
|
|
256
235
|
|
|
257
236
|
async function isActionBlocked() {
|
|
@@ -581,6 +560,7 @@ const Instauto = async (db, browser, options) => {
|
|
|
581
560
|
logger.log('Skipping already followed user', username);
|
|
582
561
|
return false;
|
|
583
562
|
}
|
|
563
|
+
|
|
584
564
|
const graphqlUser = await navigateToUserAndGetData(username);
|
|
585
565
|
|
|
586
566
|
const followedByCount = graphqlUser.edge_followed_by.count;
|
|
@@ -632,9 +612,9 @@ const Instauto = async (db, browser, options) => {
|
|
|
632
612
|
|
|
633
613
|
let numFollowedForThisUser = 0;
|
|
634
614
|
|
|
635
|
-
const
|
|
615
|
+
const { id: userId } = await navigateToUserAndGetData(username);
|
|
636
616
|
|
|
637
|
-
for await (const followersBatch of getFollowersOrFollowingGenerator({ userId
|
|
617
|
+
for await (const followersBatch of getFollowersOrFollowingGenerator({ userId, getFollowers: true })) {
|
|
638
618
|
logger.log('User followers batch', followersBatch);
|
|
639
619
|
|
|
640
620
|
for (const follower of followersBatch) {
|
|
@@ -937,16 +917,14 @@ const Instauto = async (db, browser, options) => {
|
|
|
937
917
|
throw new Error('Don\'t know what\'s my username');
|
|
938
918
|
}
|
|
939
919
|
|
|
940
|
-
const
|
|
941
|
-
const myUserId = myUserData.id;
|
|
920
|
+
const { id: myUserId } = await navigateToUserAndGetData(myUsername);
|
|
942
921
|
|
|
943
922
|
// --- END OF INITIALIZATION
|
|
944
923
|
|
|
945
924
|
async function doesUserFollowMe(username) {
|
|
946
925
|
try {
|
|
947
926
|
logger.info('Checking if user', username, 'follows us');
|
|
948
|
-
const
|
|
949
|
-
const userId = userData.id;
|
|
927
|
+
const { id: userId } = await navigateToUserAndGetData(username);
|
|
950
928
|
|
|
951
929
|
const elementHandles = await page.$x("//a[contains(.,' following')][contains(@href,'/following')]");
|
|
952
930
|
if (elementHandles.length === 0) throw new Error('Following button not found');
|