gologin 2.1.19 → 2.1.20
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/.eslintrc.json +1 -1
- package/README.md +144 -68
- package/index.d.ts +22 -3
- package/package.json +1 -1
- package/src/gologin-api.js +206 -20
- package/src/gologin.js +56 -79
- package/src/utils/utils.js +1 -0
- package/types/profile-params.d.ts +127 -0
package/.eslintrc.json
CHANGED
package/README.md
CHANGED
|
@@ -1,103 +1,179 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# GoLogin Node.js SDK
|
|
2
|
+
This package provides functionality to run and stop GoLogin profiles with node.js and then connect the profiles to automation tools like Selenium, Puppetteer, Playwright etc.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
# How does it work?
|
|
5
|
+
1. You give SDK your dev token and profile id that you want to run
|
|
6
|
+
2. SDK takes care of downloading, preparing your profile and starts the browser
|
|
7
|
+
3. SDK gives you websocket url for automation tools
|
|
8
|
+
4. You take this websocker url and connect it to the automation tool on your choice: Puppetteer, Selenium, Playwright etc
|
|
9
|
+
5. Automation tool connects to browser and you can manage it through code
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
`npm i gologin`
|
|
11
|
+
## Getting Started
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
Where is token? API token is <a href="https://app.gologin.com/#/personalArea/TokenApi" target="_blank">here</a>.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+

|
|
15
16
|
|
|
16
|
-
### Usage
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
To have an access to the page below you need <a href="https://app.gologin.com/#/createUser" target="_blank">register</a> GoLogin account.
|
|
18
|
+
### Installation
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
`npm i gologin`
|
|
22
21
|
|
|
23
22
|
### Example
|
|
24
23
|
|
|
25
24
|
```js
|
|
26
|
-
import
|
|
25
|
+
import { GologinApi } from './src/gologin-api.js';
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
const GL = GologinApi({
|
|
28
|
+
token: 'your token',
|
|
29
|
+
});
|
|
29
30
|
|
|
30
|
-
const
|
|
31
|
+
const profile = await GL.createProfileRandomFingerprint('some name');
|
|
32
|
+
const profileId = profile.id;
|
|
31
33
|
|
|
32
|
-
(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
await GL.addGologinProxyToProfile(profileId, 'us');
|
|
35
|
+
const browser = await GL.launch({ profileId });
|
|
36
|
+
const page = await browser.newPage();
|
|
37
|
+
await page.goto('https://linkedin.com');
|
|
38
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
39
|
+
await browser.close();
|
|
40
|
+
await GL.stop();
|
|
41
|
+
```
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
###
|
|
44
|
+
### Methods
|
|
45
|
+
#### constructor
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
Required options:
|
|
48
|
+
- `token` <[string]> **Required** - your API <a href="https://gologin.com/#/personalArea/TokenApi" target="_blank">token</a>
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
Optional options:
|
|
51
|
+
- `profile_id` <[string]> - profile ID (NOT PROFILE NAME) will be generated if not specified
|
|
52
|
+
- `executablePath` <[string]> path to executable Orbita file. Orbita will be downloaded automatically if not specified
|
|
53
|
+
- `extra_params` arrayof <[string]> additional flags for browser start. For example: '--headles', '--load-extentions=path/to/extension'
|
|
54
|
+
- `uploadCookiesToServer` <[boolean]> upload cookies to server after profile stopping (default false). It allows you to export cookies from api later.
|
|
55
|
+
- `writeCookesFromServer` <[boolean]> if you have predefined cookies and you want browser to import it (default true).
|
|
56
|
+
- `tmpdir` <[string]> absolute path to the directtory where you want to store user-data-dir. Default path in tmp folder will be picked if no specified
|
|
57
|
+
- `vncPort` <[integer]> port of VNC server if you using it
|
|
49
58
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
```js
|
|
60
|
+
const GL = new GoLogin({
|
|
61
|
+
token: 'your token',
|
|
62
|
+
profile_id: 'profile id',
|
|
63
|
+
extra_params: ["--headless", "--load-extentions=path/to/extension"]
|
|
64
|
+
});
|
|
65
|
+
```
|
|
54
66
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
#### createProfileRandomFingerprint - you pass os ('lin', 'win', 'mac') and profile name and we give you brand new shiny profile
|
|
68
|
+
```js
|
|
69
|
+
const GL = new GoLogin({
|
|
70
|
+
token: 'your token',
|
|
71
|
+
profile_id: 'profile id',
|
|
72
|
+
extra_params: ["--headless", "--load-extentions=path/to/extension"]
|
|
73
|
+
});
|
|
74
|
+
const profile = await gl.createProfileRandomFingerprint("some name")
|
|
75
|
+
const profileId = profile.id
|
|
61
76
|
```
|
|
62
77
|
|
|
63
|
-
### Running example:
|
|
64
78
|
|
|
65
|
-
|
|
79
|
+
#### createProfileWithCustomParams - This method creates a profile and you can pass any particular params to it. Full list of params you can find here - https://api.gologin.com/docs
|
|
80
|
+
```js
|
|
81
|
+
const GL = GoLogin({
|
|
82
|
+
"token": "your token",
|
|
83
|
+
})
|
|
84
|
+
const profile = await gl.createProfileWithCustomParams({
|
|
85
|
+
"os": "lin",
|
|
86
|
+
"name": "some name",
|
|
87
|
+
"navigator": {
|
|
88
|
+
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
|
|
89
|
+
"resolution": "1920x1080",
|
|
90
|
+
"language": "en-US",
|
|
91
|
+
"platform": "Linux x86_64",
|
|
92
|
+
"hardwareConcurrency": 8,
|
|
93
|
+
"deviceMemory": 8,
|
|
94
|
+
"maxTouchPoints": 0
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
const profileId = profile.id
|
|
98
|
+
```
|
|
66
99
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
100
|
+
#### updateUserAgentToLatestBrowser - user agent is one of the most important thing in your fingerprint. It decides which browser version to run. This method help you to keep useragent up to date.
|
|
101
|
+
```js
|
|
102
|
+
const GL = GoLogin({
|
|
103
|
+
"token": "your token",
|
|
104
|
+
})
|
|
105
|
+
await GL.updateUserAgentToLatestBrowser(["profineId1", "profileId2"], "workspceId(optional)")
|
|
106
|
+
```
|
|
70
107
|
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
- `tmpdir` <[string]> path to temporary directore for saving profiles
|
|
79
|
-
- `extra_params` arrayof <[string]> extra params for browser orbita (ex. extentions etc.)
|
|
80
|
-
- `uploadCookiesToServer` <[boolean]> upload cookies to server after profile stopping (default false)
|
|
81
|
-
- `writeCookesFromServer` <[boolean]> download cookies from server and write to profile cookies file (default true)
|
|
82
|
-
- `skipOrbitaHashChecking` <[boolean]> skip hash checking for Orbita after downloading process (default false)
|
|
108
|
+
#### addGologinProxyToProfile - Gologin provides high quality proxies with free traffic for paid users. Here you can add gologin proxy to profile, just pass country code
|
|
109
|
+
```js
|
|
110
|
+
const GL = GoLogin({
|
|
111
|
+
"token": "your token",
|
|
112
|
+
})
|
|
113
|
+
await GL.addGologinProxyToProfile("profileId", "us")
|
|
114
|
+
```
|
|
83
115
|
|
|
116
|
+
#### addCookiesToProfile - You can pass cookies to the profile and browser will import it before starting
|
|
84
117
|
```js
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
118
|
+
const GL = GoLogin({
|
|
119
|
+
"token": "your token",
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
await GL.addCookiesToProfile("profileId", [
|
|
123
|
+
{
|
|
124
|
+
"name": "session_id",
|
|
125
|
+
"value": "abc123",
|
|
126
|
+
"domain": "example.com",
|
|
127
|
+
"path": "/",
|
|
128
|
+
"expirationDate": 1719161018.307793,
|
|
129
|
+
"httpOnly": True,
|
|
130
|
+
"secure": True
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"name": "user_preferences",
|
|
134
|
+
"value": "dark_mode",
|
|
135
|
+
"domain": "example.com",
|
|
136
|
+
"path": "/settings",
|
|
137
|
+
"sameSite": "lax"
|
|
138
|
+
}
|
|
139
|
+
])
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### refreshProfilesFingerprint - Replaces your profile fingerprint with a new one
|
|
143
|
+
```js
|
|
144
|
+
const GL = GoLogin({
|
|
145
|
+
"token": "your token",
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
await GL.refreshProfilesFingerprint(["profileId1", "profileId2"])
|
|
90
149
|
```
|
|
91
150
|
|
|
92
|
-
####
|
|
151
|
+
#### changeProfileProxy - allows you to set a proxy to a profile
|
|
152
|
+
```js
|
|
153
|
+
const GL = GoLogin({
|
|
154
|
+
"token": "your token",
|
|
155
|
+
})
|
|
156
|
+
await GL.changeProfileProxy("profileId", { "mode": "http", "host": "somehost.com", "port": 109, "username": "someusername", "password": "somepassword"})
|
|
157
|
+
```
|
|
93
158
|
|
|
94
|
-
-
|
|
159
|
+
#### launch() - starts browser with profile id, returning WebSocket url for puppeteer
|
|
160
|
+
```js
|
|
161
|
+
const GL = GoLogin({
|
|
162
|
+
"token": "your token",
|
|
163
|
+
})
|
|
164
|
+
await GL.launch({ profileId: 'some profileId' })
|
|
165
|
+
```
|
|
95
166
|
|
|
96
|
-
start browser with profile id, returning WebSocket url for puppeteer
|
|
97
167
|
|
|
98
|
-
####
|
|
168
|
+
#### exit() stops browser and uploads it to the storage
|
|
169
|
+
```js
|
|
170
|
+
const GL = GoLogin({
|
|
171
|
+
"token": "your token",
|
|
172
|
+
})
|
|
173
|
+
await GL.launch({ profileId: 'some profileId' })
|
|
174
|
+
await GL.exit()
|
|
175
|
+
```
|
|
99
176
|
|
|
100
|
-
stop browser with profile id
|
|
101
177
|
|
|
102
178
|
### DEBUG
|
|
103
179
|
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type Browser } from 'puppeteer-core/lib/Browser';
|
|
2
2
|
|
|
3
|
+
import { CreateCustomBrowserValidation, BrowserProxyCreateValidation } from './types/profile-params';
|
|
4
|
+
|
|
3
5
|
export const OPERATING_SYSTEMS = {
|
|
4
6
|
win: 'win',
|
|
5
7
|
lin: 'lin',
|
|
@@ -45,12 +47,29 @@ type LaunchParams =
|
|
|
45
47
|
os: OsType;
|
|
46
48
|
};
|
|
47
49
|
|
|
48
|
-
type
|
|
50
|
+
type Cookie = {
|
|
51
|
+
name: string;
|
|
52
|
+
value: string;
|
|
53
|
+
domain: string;
|
|
54
|
+
path: string;
|
|
55
|
+
expirationDate?: number;
|
|
56
|
+
creationDate?: number;
|
|
57
|
+
hostOnly?: boolean;
|
|
58
|
+
httpOnly?: boolean;
|
|
59
|
+
sameSite?: 'no_restriction' | 'lax' | 'strict';
|
|
60
|
+
secure?: boolean;
|
|
61
|
+
session?: boolean;
|
|
62
|
+
url?: string;
|
|
63
|
+
};
|
|
49
64
|
|
|
50
65
|
type GologinApiType = {
|
|
51
|
-
launch:
|
|
66
|
+
launch: (params?: LaunchParams) => Promise<{ browser: Browser }>;
|
|
52
67
|
exit: (status = 0) => Promise<void>;
|
|
53
|
-
|
|
68
|
+
createCustom: (params: CreateCustomBrowserValidation) => Promise<string>;
|
|
69
|
+
updateProfileFingerprint: (profileId: string[]) => Promise<void>;
|
|
70
|
+
updateUserAgentToLatestBrowser: (profileIds: string[], workspaceId?: string) => Promise<void>;
|
|
71
|
+
updateProfileProxy: (profileId: string, proxyData: BrowserProxyCreateValidation) => Promise<void>;
|
|
72
|
+
addCookiesToProfile: (profileId: string, cookies: Cookie[]) => Promise<void>;
|
|
54
73
|
};
|
|
55
74
|
|
|
56
75
|
type GologinApiParams = {
|
package/package.json
CHANGED
package/src/gologin-api.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import puppeteer from 'puppeteer-core';
|
|
2
2
|
|
|
3
3
|
import GoLogin from './gologin.js';
|
|
4
|
+
import { API_URL, getOsAdvanced } from './utils/common.js';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
token: process.env.GOLOGIN_API_TOKEN,
|
|
8
|
-
profile_id: process.env.GOLOGIN_PROFILE_ID,
|
|
9
|
-
executablePath: process.env.GOLOGIN_EXECUTABLE_PATH,
|
|
10
|
-
autoUpdateBrowser: true,
|
|
11
|
-
};
|
|
12
|
-
}
|
|
6
|
+
const trafficLimitMessage =
|
|
7
|
+
'You dont have free traffic to use the proxy. Please go to app https://app.gologin.com/ and buy some traffic if you want to use the proxy';
|
|
13
8
|
|
|
14
|
-
const
|
|
9
|
+
export const getDefaultParams = () => ({
|
|
10
|
+
token: process.env.GOLOGIN_API_TOKEN,
|
|
11
|
+
profile_id: process.env.GOLOGIN_PROFILE_ID,
|
|
12
|
+
executablePath: process.env.GOLOGIN_EXECUTABLE_PATH,
|
|
13
|
+
autoUpdateBrowser: true,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const createGologinProfileManager = ({ profileId, ...params }) => {
|
|
15
17
|
const defaults = getDefaultParams();
|
|
16
18
|
const mergedParams = {
|
|
17
19
|
...defaults,
|
|
@@ -27,9 +29,7 @@ const createLegacyGologin = ({ profileId, ...params }) => {
|
|
|
27
29
|
|
|
28
30
|
const createdApis = [];
|
|
29
31
|
|
|
30
|
-
export const
|
|
31
|
-
|
|
32
|
-
export function GologinApi({ token }) {
|
|
32
|
+
export const GologinApi = ({ token }) => {
|
|
33
33
|
if (!token) {
|
|
34
34
|
throw new Error('GoLogin API token is missing');
|
|
35
35
|
}
|
|
@@ -38,7 +38,7 @@ export function GologinApi({ token }) {
|
|
|
38
38
|
const legacyGls = [];
|
|
39
39
|
|
|
40
40
|
const launchLocal = async (params) => {
|
|
41
|
-
const legacyGologin =
|
|
41
|
+
const legacyGologin = createGologinProfileManager({
|
|
42
42
|
...params,
|
|
43
43
|
token,
|
|
44
44
|
});
|
|
@@ -48,9 +48,9 @@ export function GologinApi({ token }) {
|
|
|
48
48
|
await legacyGologin.setProfileId(id);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
const
|
|
51
|
+
const startedProfile = await legacyGologin.start();
|
|
52
52
|
const browser = await puppeteer.connect({
|
|
53
|
-
browserWSEndpoint:
|
|
53
|
+
browserWSEndpoint: startedProfile.wsUrl,
|
|
54
54
|
ignoreHTTPSErrors: true,
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -61,7 +61,7 @@ export function GologinApi({ token }) {
|
|
|
61
61
|
};
|
|
62
62
|
|
|
63
63
|
const launchCloudProfile = async (params) => {
|
|
64
|
-
const legacyGologin =
|
|
64
|
+
const legacyGologin = createGologinProfileManager({
|
|
65
65
|
...params,
|
|
66
66
|
token,
|
|
67
67
|
});
|
|
@@ -94,7 +94,195 @@ export function GologinApi({ token }) {
|
|
|
94
94
|
return launchLocal(params);
|
|
95
95
|
},
|
|
96
96
|
|
|
97
|
-
async
|
|
97
|
+
async createProfileWithCustomParams(options) {
|
|
98
|
+
const response = await fetch(`${API_URL}/browser/custom`, {
|
|
99
|
+
method: 'POST',
|
|
100
|
+
headers: {
|
|
101
|
+
'Authorization': `Bearer ${token}`,
|
|
102
|
+
'User-Agent': 'gologin-api',
|
|
103
|
+
},
|
|
104
|
+
body: JSON.stringify(options),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
if (response.status === 400) {
|
|
108
|
+
throw new Error(`gologin failed account creation with status code, ${response.status} DATA ${JSON.stringify(await response.json())}`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (response.status === 500) {
|
|
112
|
+
throw new Error(`gologin failed account creation with status code, ${response.status}`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const profile = await response.json();
|
|
116
|
+
|
|
117
|
+
return profile.id;
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
async refreshProfilesFingerprint(profileIds) {
|
|
121
|
+
if (!profileIds) {
|
|
122
|
+
throw new Error('Profile ID is required');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const response = await fetch(`${API_URL}/browser/fingerprints`, {
|
|
126
|
+
headers: {
|
|
127
|
+
'Authorization': `Bearer ${token}`,
|
|
128
|
+
'User-Agent': 'gologin-api',
|
|
129
|
+
'Content-Type': 'application/json',
|
|
130
|
+
},
|
|
131
|
+
method: 'PATCH',
|
|
132
|
+
body: JSON.stringify({ browsersIds: profileIds }),
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
return response.json();
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
async createProfileRandomFingerprint(name = '') {
|
|
139
|
+
const osInfo = await getOsAdvanced();
|
|
140
|
+
const { os, osSpec } = osInfo;
|
|
141
|
+
const resultName = name || 'api-generated';
|
|
142
|
+
|
|
143
|
+
const response = await fetch(`${API_URL}/browser/quick`, {
|
|
144
|
+
method: 'POST',
|
|
145
|
+
headers: {
|
|
146
|
+
'Authorization': `Bearer ${token}`,
|
|
147
|
+
'User-Agent': 'gologin-api',
|
|
148
|
+
'Content-Type': 'application/json',
|
|
149
|
+
},
|
|
150
|
+
body: JSON.stringify({
|
|
151
|
+
os,
|
|
152
|
+
osSpec,
|
|
153
|
+
name: resultName,
|
|
154
|
+
}),
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
return response.json();
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
async updateUserAgentToLatestBrowser(profileIds, workspaceId = '') {
|
|
161
|
+
let url = `${API_URL}/browser/update_ua_to_new_browser_v`;
|
|
162
|
+
if (workspaceId) {
|
|
163
|
+
url += `?currentWorkspace=${workspaceId}`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const response = await fetch(url, {
|
|
167
|
+
method: 'PATCH',
|
|
168
|
+
headers: {
|
|
169
|
+
'Authorization': `Bearer ${token}`,
|
|
170
|
+
'User-Agent': 'gologin-api',
|
|
171
|
+
'Content-Type': 'application/json',
|
|
172
|
+
},
|
|
173
|
+
body: JSON.stringify({ browserIds: profileIds, updateUaToNewBrowserV: true, updateAllProfiles: false, testOrbita: false }),
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
return response.json();
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
async changeProfileProxy(profileId, proxyData) {
|
|
180
|
+
console.log(proxyData);
|
|
181
|
+
const response = await fetch(`${API_URL}/browser/${profileId}/proxy`, {
|
|
182
|
+
method: 'PATCH',
|
|
183
|
+
headers: {
|
|
184
|
+
Authorization: `Bearer ${token}`,
|
|
185
|
+
'user-agent': 'gologin-api',
|
|
186
|
+
'Content-Type': 'application/json',
|
|
187
|
+
},
|
|
188
|
+
body: JSON.stringify(proxyData),
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
return response.status;
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
getAvailableType(availableTrafficData) {
|
|
195
|
+
switch (true) {
|
|
196
|
+
case availableTrafficData.mobileTrafficData.trafficUsedBytes > availableTrafficData.mobileTrafficData.trafficLimitBytes:
|
|
197
|
+
return 'mobile';
|
|
198
|
+
case availableTrafficData.residentialTrafficData.trafficUsedBytes < availableTrafficData.residentialTrafficData.trafficLimitBytes:
|
|
199
|
+
return 'resident';
|
|
200
|
+
case availableTrafficData.dataCenterTrafficData.trafficUsedBytes < availableTrafficData.dataCenterTrafficData.trafficLimitBytes:
|
|
201
|
+
return 'dataCenter';
|
|
202
|
+
default:
|
|
203
|
+
return 'none';
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
async addGologinProxyToProfile(profileId, countryCode, proxyType = '') {
|
|
208
|
+
if (!proxyType) {
|
|
209
|
+
const availableTraffic = await fetch(`${API_URL}/users-proxies/geolocation/traffic`, {
|
|
210
|
+
headers: {
|
|
211
|
+
Authorization: `Bearer ${token}`,
|
|
212
|
+
'user-agent': 'gologin-api',
|
|
213
|
+
'Content-Type': 'application/json',
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const availableTrafficData = await availableTraffic.json();
|
|
218
|
+
console.log(availableTrafficData);
|
|
219
|
+
const availableType = this.getAvailableType(availableTrafficData);
|
|
220
|
+
if (availableType === 'none') {
|
|
221
|
+
throw new Error(trafficLimitMessage);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
console.log(availableType);
|
|
225
|
+
proxyType = availableType;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
let isDc = false;
|
|
229
|
+
let isMobile = false;
|
|
230
|
+
|
|
231
|
+
switch (proxyType) {
|
|
232
|
+
case 'mobile':
|
|
233
|
+
isMobile = true;
|
|
234
|
+
isDc = false;
|
|
235
|
+
break;
|
|
236
|
+
case 'resident':
|
|
237
|
+
isMobile = false;
|
|
238
|
+
isDc = false;
|
|
239
|
+
break;
|
|
240
|
+
case 'dataCenter':
|
|
241
|
+
isMobile = false;
|
|
242
|
+
isDc = true;
|
|
243
|
+
break;
|
|
244
|
+
default:
|
|
245
|
+
throw new Error('Invalid proxy type');
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const proxyResponse = await fetch(`${API_URL}/users-proxies/mobile-proxy`, {
|
|
249
|
+
headers: {
|
|
250
|
+
Authorization: `Bearer ${token}`,
|
|
251
|
+
'user-agent': 'gologin-api',
|
|
252
|
+
'Content-Type': 'application/json',
|
|
253
|
+
},
|
|
254
|
+
method: 'POST',
|
|
255
|
+
body: JSON.stringify({
|
|
256
|
+
countryCode,
|
|
257
|
+
isDc,
|
|
258
|
+
isMobile,
|
|
259
|
+
profileIdToLink: profileId,
|
|
260
|
+
}),
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
const proxy = await proxyResponse.json();
|
|
264
|
+
if (proxy.trafficLimitBytes < proxy.trafficUsedBytes) {
|
|
265
|
+
throw new Error(trafficLimitMessage);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return proxy;
|
|
269
|
+
},
|
|
270
|
+
|
|
271
|
+
async addCookiesToProfile(profileId, cookies) {
|
|
272
|
+
const response = await fetch(`${API_URL}/browser/${profileId}/cookies?fromUser=true`, {
|
|
273
|
+
method: 'POST',
|
|
274
|
+
headers: {
|
|
275
|
+
Authorization: `Bearer ${token}`,
|
|
276
|
+
'user-agent': 'gologin-api',
|
|
277
|
+
'Content-Type': 'application/json',
|
|
278
|
+
},
|
|
279
|
+
body: JSON.stringify(cookies),
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
return response.status;
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
async exit() {
|
|
98
286
|
Promise.allSettled(browsers.map((browser) => browser.close()));
|
|
99
287
|
Promise.allSettled(
|
|
100
288
|
legacyGls.map((gl) => gl.stopLocal({ posting: false })),
|
|
@@ -103,14 +291,12 @@ export function GologinApi({ token }) {
|
|
|
103
291
|
legacyGls.map((gl) => gl.stopRemote({ posting: true })),
|
|
104
292
|
);
|
|
105
293
|
},
|
|
106
|
-
|
|
107
|
-
delay,
|
|
108
294
|
};
|
|
109
295
|
|
|
110
296
|
createdApis.push(api);
|
|
111
297
|
|
|
112
298
|
return api;
|
|
113
|
-
}
|
|
299
|
+
};
|
|
114
300
|
|
|
115
301
|
export function exitAll() {
|
|
116
302
|
Promise.allSettled(createdApis.map((api) => api.exit()));
|
package/src/gologin.js
CHANGED
|
@@ -116,36 +116,6 @@ export class GoLogin {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
async getNewFingerPrint(os) {
|
|
120
|
-
debug('GETTING FINGERPRINT');
|
|
121
|
-
|
|
122
|
-
const fpResponse = await requests.get(`${API_URL}/browser/fingerprint?os=${os}`, {
|
|
123
|
-
json: true,
|
|
124
|
-
headers: {
|
|
125
|
-
'Authorization': `Bearer ${this.access_token}`,
|
|
126
|
-
'User-Agent': 'gologin-api',
|
|
127
|
-
},
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
return fpResponse?.body || {};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async profiles() {
|
|
134
|
-
const profilesResponse = await requests.get(`${API_URL}/browser/v2`, {
|
|
135
|
-
headers: {
|
|
136
|
-
'Authorization': `Bearer ${this.access_token}`,
|
|
137
|
-
'User-Agent': 'gologin-api',
|
|
138
|
-
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
if (profilesResponse.statusCode !== 200) {
|
|
143
|
-
throw new Error('Gologin /browser response error');
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return JSON.parse(profilesResponse.body);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
119
|
async getProfile(profile_id) {
|
|
150
120
|
const id = profile_id || this.profile_id;
|
|
151
121
|
debug('getProfile', this.access_token, id);
|
|
@@ -1235,48 +1205,6 @@ export class GoLogin {
|
|
|
1235
1205
|
return response.body.id;
|
|
1236
1206
|
}
|
|
1237
1207
|
|
|
1238
|
-
async createCustom(options) {
|
|
1239
|
-
debug('createCustomProfile', options);
|
|
1240
|
-
const response = await requests.post(`${API_URL}/browser/custom`, {
|
|
1241
|
-
headers: {
|
|
1242
|
-
'Authorization': `Bearer ${this.access_token}`,
|
|
1243
|
-
'User-Agent': 'gologin-api',
|
|
1244
|
-
},
|
|
1245
|
-
json: options,
|
|
1246
|
-
});
|
|
1247
|
-
|
|
1248
|
-
if (response.statusCode === 400) {
|
|
1249
|
-
throw new Error(`gologin failed account creation with status code, ${response.statusCode} DATA ${JSON.stringify(response.body.message)}`);
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
|
-
if (response.statusCode === 500) {
|
|
1253
|
-
throw new Error(`gologin failed account creation with status code, ${response.statusCode}`);
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
debug(JSON.stringify(response));
|
|
1257
|
-
|
|
1258
|
-
return response.body.id;
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
|
-
async quickCreateProfile(name = '') {
|
|
1262
|
-
const osInfo = await getOsAdvanced();
|
|
1263
|
-
const { os, osSpec } = osInfo;
|
|
1264
|
-
const resultName = name || 'api-generated';
|
|
1265
|
-
|
|
1266
|
-
return requests.post(`${API_URL}/browser/quick`, {
|
|
1267
|
-
headers: {
|
|
1268
|
-
'Authorization': `Bearer ${this.access_token}`,
|
|
1269
|
-
'User-Agent': 'gologin-api',
|
|
1270
|
-
},
|
|
1271
|
-
json: {
|
|
1272
|
-
os,
|
|
1273
|
-
osSpec,
|
|
1274
|
-
name: resultName,
|
|
1275
|
-
},
|
|
1276
|
-
})
|
|
1277
|
-
.then(res => res.body);
|
|
1278
|
-
}
|
|
1279
|
-
|
|
1280
1208
|
async delete(pid) {
|
|
1281
1209
|
const profile_id = pid || this.profile_id;
|
|
1282
1210
|
await requests.delete(`${API_URL}/browser/${profile_id}`, {
|
|
@@ -1452,7 +1380,6 @@ export class GoLogin {
|
|
|
1452
1380
|
}
|
|
1453
1381
|
|
|
1454
1382
|
async start() {
|
|
1455
|
-
|
|
1456
1383
|
await this.createStartup();
|
|
1457
1384
|
// await this.createBrowserExtension();
|
|
1458
1385
|
const wsUrl = await this.spawnBrowser();
|
|
@@ -1525,22 +1452,72 @@ export class GoLogin {
|
|
|
1525
1452
|
}
|
|
1526
1453
|
}
|
|
1527
1454
|
|
|
1455
|
+
// api for users to manage their profiles
|
|
1456
|
+
async changeProfileProxy(proxyData) {
|
|
1457
|
+
return updateProfileProxy(this.profile_id, this.access_token, proxyData);
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
async changeProfileUserAgent(userAgent) {
|
|
1461
|
+
return updateProfileUserAgent(this.profile_id, this.access_token, userAgent);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
async changeProfileResolution(resolution) {
|
|
1465
|
+
return updateProfileResolution(this.profile_id, this.access_token, resolution);
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1528
1468
|
getAvailableFonts() {
|
|
1529
1469
|
return fontsCollection
|
|
1530
1470
|
.filter(elem => elem.fileNames)
|
|
1531
1471
|
.map(elem => elem.name);
|
|
1532
1472
|
}
|
|
1533
1473
|
|
|
1534
|
-
async
|
|
1535
|
-
|
|
1474
|
+
async quickCreateProfile(name = '') {
|
|
1475
|
+
const osInfo = await getOsAdvanced();
|
|
1476
|
+
const { os, osSpec } = osInfo;
|
|
1477
|
+
const resultName = name || 'api-generated';
|
|
1478
|
+
|
|
1479
|
+
return requests.post(`${API_URL}/browser/quick`, {
|
|
1480
|
+
headers: {
|
|
1481
|
+
'Authorization': `Bearer ${this.access_token}`,
|
|
1482
|
+
'User-Agent': 'gologin-api',
|
|
1483
|
+
},
|
|
1484
|
+
json: {
|
|
1485
|
+
os,
|
|
1486
|
+
osSpec,
|
|
1487
|
+
name: resultName,
|
|
1488
|
+
},
|
|
1489
|
+
})
|
|
1490
|
+
.then(res => res.body);
|
|
1536
1491
|
}
|
|
1537
1492
|
|
|
1538
|
-
async
|
|
1539
|
-
|
|
1493
|
+
async profiles() {
|
|
1494
|
+
const profilesResponse = await requests.get(`${API_URL}/browser/v2`, {
|
|
1495
|
+
headers: {
|
|
1496
|
+
'Authorization': `Bearer ${this.access_token}`,
|
|
1497
|
+
'User-Agent': 'gologin-api',
|
|
1498
|
+
|
|
1499
|
+
},
|
|
1500
|
+
});
|
|
1501
|
+
|
|
1502
|
+
if (profilesResponse.statusCode !== 200) {
|
|
1503
|
+
throw new Error('Gologin /browser response error');
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
return JSON.parse(profilesResponse.body);
|
|
1540
1507
|
}
|
|
1541
1508
|
|
|
1542
|
-
async
|
|
1543
|
-
|
|
1509
|
+
async getNewFingerPrint(os) {
|
|
1510
|
+
debug('GETTING FINGERPRINT');
|
|
1511
|
+
|
|
1512
|
+
const fpResponse = await requests.get(`${API_URL}/browser/fingerprint?os=${os}`, {
|
|
1513
|
+
json: true,
|
|
1514
|
+
headers: {
|
|
1515
|
+
'Authorization': `Bearer ${this.access_token}`,
|
|
1516
|
+
'User-Agent': 'gologin-api',
|
|
1517
|
+
},
|
|
1518
|
+
});
|
|
1519
|
+
|
|
1520
|
+
return fpResponse?.body || {};
|
|
1544
1521
|
}
|
|
1545
1522
|
}
|
|
1546
1523
|
|
package/src/utils/utils.js
CHANGED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export type OS = 'lin' | 'mac' | 'win' | 'android';
|
|
2
|
+
export type T_OS_SPEC = 'M1' | 'M2' | 'M3' | 'M3' | 'win11' | '';
|
|
3
|
+
|
|
4
|
+
export type IBookmarkFoldersObj = {
|
|
5
|
+
[key: string]: {
|
|
6
|
+
name: string;
|
|
7
|
+
children: Array<{
|
|
8
|
+
name: string;
|
|
9
|
+
url: string;
|
|
10
|
+
}>;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type NavigatorModel = {
|
|
15
|
+
userAgent: string;
|
|
16
|
+
resolution: string;
|
|
17
|
+
language: string;
|
|
18
|
+
platform: string;
|
|
19
|
+
hardwareConcurrency: number;
|
|
20
|
+
deviceMemory: number;
|
|
21
|
+
maxTouchPoints?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type TimezoneModel = {
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
fillBasedOnIp: boolean;
|
|
27
|
+
timezone: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type GeolocationModel = {
|
|
31
|
+
mode: 'prompt' | 'block' | 'allow';
|
|
32
|
+
enabled: boolean;
|
|
33
|
+
customize: boolean;
|
|
34
|
+
fillBasedOnIp: boolean;
|
|
35
|
+
latitude: number;
|
|
36
|
+
longitude: number;
|
|
37
|
+
accuracy: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type AudioContextModel = {
|
|
41
|
+
enable: boolean;
|
|
42
|
+
noiseValue: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type CanvasModel = {
|
|
46
|
+
mode: 'off' | 'noise';
|
|
47
|
+
noise?: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type FontsModel = {
|
|
51
|
+
enableMasking: boolean;
|
|
52
|
+
enableDOMRect: boolean;
|
|
53
|
+
families: string[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type MediaDevicesModel = {
|
|
57
|
+
enableMasking: boolean;
|
|
58
|
+
videoInputs: number;
|
|
59
|
+
audioInputs: number;
|
|
60
|
+
audioOutputs: number;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type WebRTCModel = {
|
|
64
|
+
mode: 'real' | 'public';
|
|
65
|
+
enabled: boolean;
|
|
66
|
+
customize: boolean;
|
|
67
|
+
localIpMasking: boolean;
|
|
68
|
+
fillBasedOnIp: boolean;
|
|
69
|
+
publicIp: string;
|
|
70
|
+
localIps: string[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type WebGlModel = {
|
|
74
|
+
mode: 'off' | 'noise';
|
|
75
|
+
getClientRectsNoise: number;
|
|
76
|
+
noise?: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type ClientRectsModel = {
|
|
80
|
+
mode: 'off' | 'noise';
|
|
81
|
+
noise: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export type WebGlMetadataModel {
|
|
85
|
+
mode: 'off' | 'mask';
|
|
86
|
+
vendor: string;
|
|
87
|
+
renderer: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export type BrowserProxyCreateValidation {
|
|
91
|
+
mode: 'http' | 'https' | 'socks4' | 'socks5' | 'geolocation' | 'none' | 'tor' | 'gologin';
|
|
92
|
+
host: string;
|
|
93
|
+
port: number;
|
|
94
|
+
username?: string;
|
|
95
|
+
password?: string;
|
|
96
|
+
changeIpUrl?: string;
|
|
97
|
+
autoProxyRegion?: string;
|
|
98
|
+
torProxyRegion?: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export declare class CreateCustomBrowserValidation {
|
|
102
|
+
name?: string;
|
|
103
|
+
notes?: string;
|
|
104
|
+
autoLang?: boolean;
|
|
105
|
+
lockEnabled?: boolean;
|
|
106
|
+
folderName?: string;
|
|
107
|
+
bookmarks?: IBookmarkFoldersObj;
|
|
108
|
+
os: OS;
|
|
109
|
+
osSpec?: T_OS_SPEC;
|
|
110
|
+
devicePixelRatio?: number;
|
|
111
|
+
navigator?: NavigatorModel;
|
|
112
|
+
proxy?: BrowserProxyCreateValidation;
|
|
113
|
+
dns?: string;
|
|
114
|
+
timezone?: TimezoneModel;
|
|
115
|
+
geolocation?: GeolocationModel;
|
|
116
|
+
audioContext?: AudioContextModel;
|
|
117
|
+
canvas?: CanvasModel;
|
|
118
|
+
fonts?: FontsModel;
|
|
119
|
+
mediaDevices?: MediaDevicesModel;
|
|
120
|
+
webRTC?: WebRTCModel;
|
|
121
|
+
webGL?: WebGlModel;
|
|
122
|
+
clientRects?: ClientRectsModel;
|
|
123
|
+
webGLMetadata?: WebGlMetadataModel;
|
|
124
|
+
chromeExtensions?: string[];
|
|
125
|
+
userChromeExtensions?: string[];
|
|
126
|
+
folders?: string[];
|
|
127
|
+
}
|