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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instauto",
3
- "version": "9.1.2",
3
+ "version": "9.1.3",
4
4
  "description": "Instagram automation library written in Node.js",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
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
- // https://github.com/mifi/SimpleInstaBot/issues/36
225
- if (graphqlUserMissing) {
226
- // https://stackoverflow.com/questions/37593025/instagram-api-get-the-userid
227
- // https://stackoverflow.com/questions/17373886/how-can-i-get-a-users-media-from-instagram-without-authenticating-as-a-user
228
- const found = await safeGotoUser(`${instagramBaseUrl}/${encodeURIComponent(username)}?__a=1`);
229
- if (!found) throw new Error('User not found');
230
-
231
- const json = await getPageJson();
232
-
233
- const { user } = json.graphql;
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 userData = await navigateToUserAndGetData(username);
615
+ const { id: userId } = await navigateToUserAndGetData(username);
636
616
 
637
- for await (const followersBatch of getFollowersOrFollowingGenerator({ userId: userData.id, getFollowers: true })) {
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 myUserData = await navigateToUserAndGetData(myUsername);
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 userData = await navigateToUserAndGetData(username);
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');