instauto 9.2.1 → 9.4.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 CHANGED
@@ -78,6 +78,14 @@ pm2 startup
78
78
 
79
79
  Now it will run automatically on reboot! 🙌
80
80
 
81
+ ## Running in Docker
82
+
83
+ We've added a Docker support for instauto! In the **environment** section of your `docker-compose.yml` you need to specify your configuration for login and performance. If you want to raise another container, just copy the service with diff name and run the compose. You'll need to specify different ports.
84
+
85
+ ```bash
86
+ docker-compose --profile instauto up -d
87
+ ```
88
+
81
89
  ## Donate 🙈
82
90
 
83
91
  This project is maintained by me alone. The project will always remain free and open source, but if it's useful for you, consider supporting me. :) It will give me extra motivation to improve it.
@@ -87,6 +95,7 @@ This project is maintained by me alone. The project will always remain free and
87
95
  ## Credits
88
96
 
89
97
  - Icons made by [smalllikeart](https://www.flaticon.com/authors/smalllikeart) & [Freepik](https://www.flaticon.com/authors/freepik) from [www.flaticon.com](https://www.flaticon.com/)
98
+ - Docker compose by https://github.com/maxxxdj
90
99
 
91
100
  ---
92
101
 
package/dist/db.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ export interface FollowedUser {
2
+ username: string;
3
+ time: number;
4
+ failed?: boolean;
5
+ noActionTaken?: boolean;
6
+ }
7
+ export interface LikedPhoto {
8
+ username: string;
9
+ href: string;
10
+ time: number;
11
+ }
12
+ export default function JSONDB({ followedDbPath, unfollowedDbPath, likedPhotosDbPath, logger, }: {
13
+ followedDbPath: string;
14
+ unfollowedDbPath: string;
15
+ likedPhotosDbPath: string;
16
+ logger?: Console;
17
+ }): Promise<{
18
+ save: () => Promise<void>;
19
+ addPrevFollowedUser: (user: FollowedUser) => Promise<void>;
20
+ getPrevFollowedUser: (username: string) => FollowedUser | undefined;
21
+ addPrevUnfollowedUser: (user: FollowedUser) => Promise<void>;
22
+ getPrevFollowedUsers: () => FollowedUser[];
23
+ getFollowedLastTimeUnit: (timeUnit: number) => FollowedUser[];
24
+ getPrevUnfollowedUsers: () => FollowedUser[];
25
+ getUnfollowedLastTimeUnit: (timeUnit: number) => FollowedUser[];
26
+ getPrevLikedPhotos: () => LikedPhoto[];
27
+ getLikedPhotosLastTimeUnit: (timeUnit: number) => LikedPhoto[];
28
+ addLikedPhoto: ({ username, href, time }: LikedPhoto) => Promise<void>;
29
+ getTotalFollowedUsers: () => number;
30
+ getTotalUnfollowedUsers: () => number;
31
+ getTotalLikedPhotos: () => number;
32
+ }>;
33
+ export type JSONDBInstance = Awaited<ReturnType<typeof JSONDB>>;
34
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE;AAC3G,MAAM,WAAW,UAAU;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAE5E,wBAA8B,MAAM,CAAC,EACnC,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EAEjB,MAAgB,GACjB,EAAE;IACD,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;;gCAoE0C,YAAY;oCAJd,MAAM;kCAsBF,YAAY;;wCA3BZ,MAAM;;0CAsBJ,MAAM;;2CAxCL,MAAM;8CAKG,UAAU;;;;GA+DlE;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC"}
package/dist/db.js ADDED
@@ -0,0 +1,99 @@
1
+ import { readFile, writeFile } from 'node:fs/promises';
2
+ import keyBy from 'lodash/keyBy.js';
3
+ export default async function JSONDB({ followedDbPath, unfollowedDbPath, likedPhotosDbPath, logger = console, }) {
4
+ let prevFollowedUsers = {};
5
+ let prevUnfollowedUsers = {};
6
+ let prevLikedPhotos = [];
7
+ async function trySaveDb() {
8
+ try {
9
+ await writeFile(followedDbPath, JSON.stringify(Object.values(prevFollowedUsers)));
10
+ await writeFile(unfollowedDbPath, JSON.stringify(Object.values(prevUnfollowedUsers)));
11
+ await writeFile(likedPhotosDbPath, JSON.stringify(prevLikedPhotos));
12
+ }
13
+ catch {
14
+ logger.error('Failed to save database');
15
+ }
16
+ }
17
+ async function tryLoadDb() {
18
+ try {
19
+ prevFollowedUsers = keyBy(JSON.parse(await readFile(followedDbPath, 'utf8')), 'username');
20
+ }
21
+ catch {
22
+ logger.warn('No followed database found');
23
+ }
24
+ try {
25
+ prevUnfollowedUsers = keyBy(JSON.parse(await readFile(unfollowedDbPath, 'utf8')), 'username');
26
+ }
27
+ catch {
28
+ logger.warn('No unfollowed database found');
29
+ }
30
+ try {
31
+ prevLikedPhotos = JSON.parse(await readFile(likedPhotosDbPath, 'utf8'));
32
+ }
33
+ catch {
34
+ logger.warn('No likes database found');
35
+ }
36
+ }
37
+ function getPrevLikedPhotos() {
38
+ return prevLikedPhotos;
39
+ }
40
+ function getTotalLikedPhotos() {
41
+ return getPrevLikedPhotos().length; // TODO performance
42
+ }
43
+ function getLikedPhotosLastTimeUnit(timeUnit) {
44
+ const now = Date.now();
45
+ return getPrevLikedPhotos().filter((u) => now - u.time < timeUnit);
46
+ }
47
+ async function addLikedPhoto({ username, href, time }) {
48
+ prevLikedPhotos.push({ username, href, time });
49
+ await trySaveDb();
50
+ }
51
+ function getPrevFollowedUsers() {
52
+ return Object.values(prevFollowedUsers);
53
+ }
54
+ function getTotalFollowedUsers() {
55
+ return getPrevFollowedUsers().length; // TODO performance
56
+ }
57
+ function getFollowedLastTimeUnit(timeUnit) {
58
+ const now = Date.now();
59
+ return getPrevFollowedUsers().filter((u) => now - u.time < timeUnit);
60
+ }
61
+ function getPrevFollowedUser(username) {
62
+ return prevFollowedUsers[username];
63
+ }
64
+ async function addPrevFollowedUser(user) {
65
+ prevFollowedUsers[user.username] = user;
66
+ await trySaveDb();
67
+ }
68
+ function getPrevUnfollowedUsers() {
69
+ return Object.values(prevUnfollowedUsers);
70
+ }
71
+ function getTotalUnfollowedUsers() {
72
+ return getPrevUnfollowedUsers().length; // TODO performance
73
+ }
74
+ function getUnfollowedLastTimeUnit(timeUnit) {
75
+ const now = Date.now();
76
+ return getPrevUnfollowedUsers().filter((u) => now - u.time < timeUnit);
77
+ }
78
+ async function addPrevUnfollowedUser(user) {
79
+ prevUnfollowedUsers[user.username] = user;
80
+ await trySaveDb();
81
+ }
82
+ await tryLoadDb();
83
+ return {
84
+ save: trySaveDb,
85
+ addPrevFollowedUser,
86
+ getPrevFollowedUser,
87
+ addPrevUnfollowedUser,
88
+ getPrevFollowedUsers,
89
+ getFollowedLastTimeUnit,
90
+ getPrevUnfollowedUsers,
91
+ getUnfollowedLastTimeUnit,
92
+ getPrevLikedPhotos,
93
+ getLikedPhotosLastTimeUnit,
94
+ addLikedPhoto,
95
+ getTotalFollowedUsers,
96
+ getTotalUnfollowedUsers,
97
+ getTotalLikedPhotos,
98
+ };
99
+ }
@@ -0,0 +1,146 @@
1
+ import type { Browser, Page } from 'puppeteer';
2
+ import { type FollowedUser, type JSONDBInstance } from './db.ts';
3
+ type Logger = Pick<Console, 'log' | 'info' | 'debug' | 'error' | 'trace' | 'warn'>;
4
+ declare global {
5
+ interface Window {
6
+ instautoSleep: (ms: number) => Promise<void>;
7
+ instautoLog: (...args: unknown[]) => void;
8
+ instautoOnImageLiked: (href: string) => void;
9
+ _sharedData?: {
10
+ config?: {
11
+ viewer?: {
12
+ username?: string;
13
+ };
14
+ };
15
+ };
16
+ }
17
+ }
18
+ type LikeMediaType = 'image' | 'video' | 'unknown';
19
+ interface LikeMediaData {
20
+ mediaType: LikeMediaType;
21
+ mediaDesc: string;
22
+ src?: string | undefined;
23
+ alt?: string | undefined;
24
+ poster?: string | undefined;
25
+ }
26
+ type ShouldLikeMedia = (data: LikeMediaData) => boolean;
27
+ interface ShouldFollowUserData {
28
+ username: string;
29
+ isVerified: boolean;
30
+ isBusinessAccount: boolean;
31
+ isProfessionalAccount: boolean;
32
+ fullName: string;
33
+ biography: string;
34
+ profilePicUrlHd: string;
35
+ externalUrl: string | null;
36
+ businessCategoryName: string | null;
37
+ categoryName: string | null;
38
+ }
39
+ type ShouldFollowUser = (data: ShouldFollowUserData) => boolean;
40
+ export interface InstautoOptions {
41
+ instagramBaseUrl?: string;
42
+ cookiesPath: string;
43
+ username?: string;
44
+ password?: string;
45
+ enableCookies?: boolean;
46
+ randomizeUserAgent?: boolean;
47
+ userAgent?: string;
48
+ maxFollowsPerHour?: number;
49
+ maxFollowsPerDay?: number;
50
+ maxLikesPerDay?: number;
51
+ followUserRatioMin?: number;
52
+ followUserRatioMax?: number;
53
+ followUserMaxFollowers?: number | null;
54
+ followUserMaxFollowing?: number | null;
55
+ followUserMinFollowers?: number | null;
56
+ followUserMinFollowing?: number | null;
57
+ shouldFollowUser?: ShouldFollowUser | null;
58
+ shouldLikeMedia?: ShouldLikeMedia | null;
59
+ dontUnfollowUntilTimeElapsed?: number;
60
+ excludeUsers?: string[];
61
+ dryRun?: boolean;
62
+ screenshotOnError?: boolean;
63
+ screenshotsPath?: string;
64
+ logger?: Logger;
65
+ }
66
+ interface LikeUserImagesOptions {
67
+ username?: string | undefined;
68
+ likeImagesMin?: number | undefined;
69
+ likeImagesMax?: number | undefined;
70
+ }
71
+ interface ProcessUserFollowersOptions {
72
+ maxFollowsPerUser?: number | undefined;
73
+ skipPrivate?: boolean | undefined;
74
+ enableLikeImages?: boolean | undefined;
75
+ likeImagesMin?: number | undefined;
76
+ likeImagesMax?: number | undefined;
77
+ }
78
+ interface ProcessUsersFollowersOptions {
79
+ usersToFollowFollowersOf: string[];
80
+ maxFollowsTotal?: number | undefined;
81
+ skipPrivate?: boolean | undefined;
82
+ enableFollow?: boolean | undefined;
83
+ enableLikeImages?: boolean | undefined;
84
+ likeImagesMin?: number | undefined;
85
+ likeImagesMax?: number | undefined;
86
+ }
87
+ interface UnfollowOptions {
88
+ limit?: number | undefined;
89
+ }
90
+ interface UnfollowOldOptions {
91
+ ageInDays?: number | undefined;
92
+ limit?: number | undefined;
93
+ }
94
+ interface SafelyFollowUserListOptions {
95
+ users: string[];
96
+ skipPrivate?: boolean | undefined;
97
+ limit?: number | undefined;
98
+ }
99
+ interface InstagramUser {
100
+ id: string;
101
+ username?: string;
102
+ edge_followed_by: {
103
+ count: number;
104
+ };
105
+ edge_follow: {
106
+ count: number;
107
+ };
108
+ is_private: boolean;
109
+ is_verified: boolean;
110
+ is_business_account: boolean;
111
+ is_professional_account: boolean;
112
+ full_name: string;
113
+ biography: string;
114
+ profile_pic_url_hd: string;
115
+ external_url: string | null;
116
+ business_category_name: string | null;
117
+ category_name: string | null;
118
+ }
119
+ export interface InstautoApi {
120
+ followUserFollowers: (username: string, options?: ProcessUserFollowersOptions) => Promise<void>;
121
+ unfollowNonMutualFollowers: (options?: UnfollowOptions) => Promise<number>;
122
+ unfollowAllUnknown: (options?: UnfollowOptions) => Promise<number>;
123
+ unfollowOldFollowed: (options: UnfollowOldOptions) => Promise<number>;
124
+ followUser: (username: string) => Promise<void>;
125
+ unfollowUser: (username: string) => Promise<FollowedUser>;
126
+ likeUserImages: (options?: LikeUserImagesOptions) => Promise<void>;
127
+ sleep: (ms: number, deviation?: number) => Promise<void>;
128
+ listManuallyFollowedUsers: () => Promise<string[]>;
129
+ getFollowersOrFollowing: (options: {
130
+ userId: string;
131
+ getFollowers?: boolean;
132
+ }) => Promise<string[]>;
133
+ getUsersWhoLikedContent: (options: {
134
+ contentId: string;
135
+ }) => AsyncGenerator<string[], string[], void>;
136
+ safelyUnfollowUserList: (usersToUnfollow: AsyncIterable<string | string[]> | Iterable<string | string[]>, limit?: number, condition?: (username: string) => boolean | Promise<boolean>) => Promise<number>;
137
+ safelyFollowUserList: (options: SafelyFollowUserListOptions) => Promise<void>;
138
+ getPage: () => Page;
139
+ followUsersFollowers: (options: ProcessUsersFollowersOptions) => Promise<void>;
140
+ doesUserFollowMe: (username: string) => Promise<boolean | undefined>;
141
+ navigateToUserAndGetData: (username: string) => Promise<InstagramUser | undefined>;
142
+ }
143
+ declare const Instauto: (db: JSONDBInstance, browser: Browser, options: InstautoOptions) => Promise<InstautoApi>;
144
+ export default Instauto;
145
+ export { default as JSONDB } from './db.ts';
146
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}