gologin 2.1.21 → 2.1.23

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/src/gologin.js CHANGED
@@ -1,12 +1,11 @@
1
+ import * as Sentry from '@sentry/node';
1
2
  import { execFile, spawn } from 'child_process';
2
3
  import debugDefault from 'debug';
3
4
  import decompress from 'decompress';
4
5
  import decompressUnzip from 'decompress-unzip';
5
6
  import { existsSync, mkdirSync, promises as _promises } from 'fs';
6
- import { get as _get } from 'https';
7
7
  import { tmpdir } from 'os';
8
8
  import { dirname, join, resolve as _resolve, sep } from 'path';
9
- import requests from 'requestretry';
10
9
  import rimraf from 'rimraf';
11
10
  import { SocksProxyAgent } from 'socks-proxy-agent';
12
11
  import { fileURLToPath } from 'url';
@@ -29,10 +28,11 @@ import {
29
28
  import ExtensionsManager from './extensions/extensions-manager.js';
30
29
  import { archiveProfile } from './profile/profile-archiver.js';
31
30
  import { checkAutoLang } from './utils/browser.js';
32
- import { API_URL, ensureDirectoryExists, getOsAdvanced } from './utils/common.js';
31
+ import { API_URL, ensureDirectoryExists, FALLBACK_API_URL, getOsAdvanced } from './utils/common.js';
33
32
  import { STORAGE_GATEWAY_BASE_URL } from './utils/constants.js';
34
33
  import { get, isPortReachable } from './utils/utils.js';
35
34
  export { exitAll, GologinApi } from './gologin-api.js';
35
+ import { checkSocksProxy, makeRequest } from './utils/http.js';
36
36
  import { zeroProfileBookmarks } from './utils/zero-profile-bookmarks.js';
37
37
  import { zeroProfilePreferences } from './utils/zero-profile-preferences.js';
38
38
  const { access, unlink, writeFile, readFile, mkdir, copyFile } = _promises;
@@ -70,7 +70,7 @@ export class GoLogin {
70
70
  this.checkBrowserUpdate = options.checkBrowserUpdate ?? true;
71
71
  this.browserChecker = new BrowserChecker(options.skipOrbitaHashChecking);
72
72
  this.uploadCookiesToServer = options.uploadCookiesToServer || false;
73
- this.writeCookiesFromServer = options.writeCookiesFromServer;
73
+ this.writeCookiesFromServer = options.writeCookiesFromServer ?? true;
74
74
  this.remote_debugging_port = options.remote_debugging_port || 0;
75
75
  this.timezone = options.timezone;
76
76
  this.extensionPathsToInstall = [];
@@ -79,6 +79,13 @@ export class GoLogin {
79
79
  this.processSpawned = null;
80
80
  this.processKillTimeout = 1 * 1000;
81
81
 
82
+ if (process.env.DISABLE_TELEMETRY !== 'true') {
83
+ Sentry.init({
84
+ dsn: 'https://a13d5939a60ae4f6583e228597f1f2a0@sentry-new.amzn.pro/24',
85
+ tracesSampleRate: 1.0,
86
+ });
87
+ }
88
+
82
89
  if (options.tmpdir) {
83
90
  this.tmpdir = options.tmpdir;
84
91
  if (!existsSync(this.tmpdir)) {
@@ -93,7 +100,36 @@ export class GoLogin {
93
100
  }
94
101
 
95
102
  async checkBrowser(majorVersion) {
96
- this.executablePath = await this.browserChecker.checkBrowser(majorVersion);
103
+ this.executablePath = await this.browserChecker.checkBrowser({
104
+ autoUpdateBrowser: this.autoUpdateBrowser,
105
+ checkBrowserUpdate: this.checkBrowserUpdate,
106
+ majorVersion,
107
+ });
108
+ }
109
+
110
+ async checkAndDownloadBrowserByOpts(opts = {}) {
111
+ const { majorVersions = [], lastActualCount = 5 } = opts;
112
+
113
+ let versionsToDownload = majorVersions;
114
+ if (!(Array.isArray(versionsToDownload) && versionsToDownload.length)) {
115
+ versionsToDownload = [];
116
+
117
+ const { latestVersion: browserLatestVersion } = await this.browserChecker.getLatestBrowserVersion();
118
+ const [latestBrowserMajorVersion] = browserLatestVersion.split('.');
119
+ const latestVersionNumber = Number(latestBrowserMajorVersion);
120
+
121
+ for (let i = latestVersionNumber; i > latestVersionNumber - lastActualCount; i--) {
122
+ versionsToDownload.push(i.toString());
123
+ }
124
+ }
125
+
126
+ for (const majorVersion of versionsToDownload) {
127
+ await this.browserChecker.checkBrowser({
128
+ autoUpdateBrowser: true,
129
+ checkBrowserUpdate: true,
130
+ majorVersion,
131
+ });
132
+ }
97
133
  }
98
134
 
99
135
  async setProfileId(profile_id) {
@@ -103,59 +139,14 @@ export class GoLogin {
103
139
  this.bookmarksFilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`, 'Default', 'Bookmarks');
104
140
  }
105
141
 
106
- async getToken(username, password) {
107
- const data = await requests.post(`${API_URL}/user/login`, {
108
- json: {
109
- username,
110
- password,
111
- },
112
- });
113
-
114
- if (!Reflect.has(data, 'body.access_token')) {
115
- throw new Error(`gologin auth failed with status code, ${data.statusCode} DATA ${JSON.stringify(data)}`);
116
- }
117
- }
118
-
119
142
  async getProfile(profile_id) {
120
143
  const id = profile_id || this.profile_id;
121
144
  debug('getProfile', this.access_token, id);
122
- const profileResponse = await requests.get(`${API_URL}/browser/features/${id}/info-for-run`, {
123
- headers: {
124
- 'Authorization': `Bearer ${this.access_token}`,
125
- 'User-Agent': 'gologin-api',
126
- },
127
- });
128
-
129
- debug('profileResponse', profileResponse.statusCode, profileResponse.body);
130
-
131
- const { body: errorBody = '' } = profileResponse;
132
- const backendErrorHeader = 'backend@error::';
133
- if (errorBody.includes(backendErrorHeader)) {
134
- const errorData =
135
- errorBody
136
- .replace(backendErrorHeader, '')
137
- .slice(1, -1);
138
-
139
- throw new Error(errorData);
140
- }
145
+ const profileResponse = await makeRequest(`${API_URL}/browser/features/${id}/info-for-run`, {
146
+ method: 'GET',
147
+ }, { token: this.access_token, fallbackUrl: `${FALLBACK_API_URL}/browser/features/${id}/info-for-run` });
141
148
 
142
- if (profileResponse.statusCode === 404) {
143
- throw new Error(JSON.parse(profileResponse.body).message);
144
- }
145
-
146
- if (profileResponse.statusCode === 403) {
147
- throw new Error(JSON.parse(profileResponse.body).message);
148
- }
149
-
150
- if (profileResponse.statusCode !== 200) {
151
- throw new Error(`Gologin /browser/${id} response error ${profileResponse.statusCode} INVALID TOKEN OR PROFILE NOT FOUND`);
152
- }
153
-
154
- if (profileResponse.statusCode === 401) {
155
- throw new Error('invalid token');
156
- }
157
-
158
- return JSON.parse(profileResponse.body);
149
+ return JSON.parse(profileResponse);
159
150
  }
160
151
 
161
152
  async emptyProfile() {
@@ -191,23 +182,21 @@ export class GoLogin {
191
182
  debug('Getting signed URL for S3');
192
183
 
193
184
  const bodyBufferBiteLength = Buffer.byteLength(fileBuff);
194
- console.log('BUFFER SIZE', bodyBufferBiteLength);
195
185
 
196
- await requests.put(this.storageGatewayUrl, {
186
+ await makeRequest(this.storageGatewayUrl, {
197
187
  headers: {
198
- Authorization: `Bearer ${this.access_token}`,
199
188
  browserId: this.profile_id,
200
189
  'Content-Type': 'application/zip',
201
190
  'Content-Length': bodyBufferBiteLength,
202
191
  },
192
+ method: 'PUT',
203
193
  body: fileBuff,
204
194
  maxBodyLength: Infinity,
205
195
  maxContentLength: Infinity,
206
196
  maxAttempts: 3,
207
197
  retryDelay: 2000,
208
198
  timeout: 30 * 1000,
209
- fullResponse: false,
210
- });
199
+ }, { token: this.access_token });
211
200
 
212
201
  console.log('Profile has been uploaded to S3 successfully');
213
202
  }
@@ -230,7 +219,6 @@ export class GoLogin {
230
219
  const resolution = (profileData.navigator && profileData.navigator.resolution) || '1920x1080';
231
220
  const [screenWidth, screenHeight] = resolution.split('x').map(Number);
232
221
  const langHeader = (profileData.navigator && profileData.navigator.language) || '';
233
- console.log('langHeader', langHeader);
234
222
  const splittedLangs = langHeader ? langHeader.split(',')[0] : 'en-US';
235
223
 
236
224
  const startupUrl = (profileData.startUrl || '').trim().split(',')[0];
@@ -495,7 +483,7 @@ export class GoLogin {
495
483
  ExtensionsManagerInst.apiUrl = API_URL;
496
484
  await ExtensionsManagerInst.init()
497
485
  .then(() => ExtensionsManagerInst.updateExtensions())
498
- .catch(() => { });
486
+ .catch(() => {});
499
487
  ExtensionsManagerInst.accessToken = this.access_token;
500
488
 
501
489
  await ExtensionsManagerInst.getExtensionsPolicies();
@@ -717,20 +705,41 @@ export class GoLogin {
717
705
 
718
706
  const proxyUrl = `${proxy.mode}://${proxy.username}:${proxy.password}@${proxy.host}:${proxy.port}`;
719
707
  debug(`getTimeZone start ${TIMEZONE_URL}`, proxyUrl);
720
- data = await requests.get(TIMEZONE_URL, { proxy: proxyUrl, timeout: 13 * 1000, maxAttempts: 3 });
708
+ data = await makeRequest(TIMEZONE_URL, { proxy: proxyUrl, timeout: 13 * 1000, maxAttempts: 3, method: 'GET' });
721
709
  } else {
722
- data = await requests.get(TIMEZONE_URL, { timeout: 13 * 1000, maxAttempts: 3 });
723
- }
710
+ data = await makeRequest(TIMEZONE_URL, { timeout: 13 * 1000, maxAttempts: 3, method: 'GET' });
711
+ }
712
+
713
+ debug('getTimeZone finish', data);
714
+ this._tz = JSON.parse(data);
715
+
716
+ if (proxy?.id) {
717
+ const statusBody = {
718
+ proxies: [
719
+ {
720
+ id: proxy.id,
721
+ status: true,
722
+ country: this._tz.country,
723
+ city: this._tz.city,
724
+ lastIp: this._tz.ip,
725
+ timezone: this._tz.timezone,
726
+ checkDate: Math.floor(Date.now() / 1000),
727
+ },
728
+ ],
729
+ };
724
730
 
725
- debug('getTimeZone finish', data.body);
726
- this._tz = JSON.parse(data.body);
731
+ await makeRequest(
732
+ `${API_URL}/proxy/set_proxy_statuses`,
733
+ { timeout: 13 * 1000, maxAttempts: 3, method: 'POST', json: statusBody },
734
+ { token: this.access_token, fallbackUrl: `${FALLBACK_API_URL}/proxy/set_proxy_statuses` },
735
+ ).catch();
736
+ }
727
737
 
728
738
  return this._tz.timezone;
729
739
  }
730
740
 
731
741
  async getTimezoneWithSocks(params) {
732
742
  const { host, port, username = '', password = '' } = params;
733
- let body;
734
743
 
735
744
  let proxy = 'socks://';
736
745
  if (username) {
@@ -740,28 +749,10 @@ export class GoLogin {
740
749
 
741
750
  proxy += host + ':' + port;
742
751
  const agent = new SocksProxyAgent(proxy);
743
- const checkData = await new Promise((resolve, reject) => {
744
- _get(TIMEZONE_URL, { agent, timeout: 10000 }, (res) => {
745
- let resultResponse = '';
746
- res.on('data', (data) => resultResponse += data);
747
-
748
- res.on('end', () => {
749
- let parsedData;
750
- try {
751
- parsedData = JSON.parse(resultResponse);
752
- } catch (e) {
753
- reject(e);
754
- }
755
752
 
756
- resolve({
757
- ...res,
758
- body: parsedData,
759
- });
760
- });
761
- }).on('error', (err) => reject(err));
762
- });
753
+ const checkData = await checkSocksProxy(agent);
763
754
 
764
- body = checkData.body || {};
755
+ const body = checkData || {};
765
756
  if (!body.ip && checkData.statusCode.toString().startsWith('4')) {
766
757
  throw checkData;
767
758
  }
@@ -769,6 +760,28 @@ export class GoLogin {
769
760
  debug('getTimeZone finish', body.body);
770
761
  this._tz = body;
771
762
 
763
+ if (proxy.id) {
764
+ const statusBody = {
765
+ proxies: [
766
+ {
767
+ id: proxy.id,
768
+ status: true,
769
+ country: this._tz.country,
770
+ city: this._tz.city,
771
+ lastIp: this._tz.ip,
772
+ timezone: this._tz.timezone,
773
+ checkDate: Math.floor(Date.now() / 1000),
774
+ },
775
+ ],
776
+ };
777
+
778
+ await makeRequest(
779
+ `${API_URL}/proxy/set_proxy_statuses`,
780
+ { timeout: 13 * 1000, maxAttempts: 3, method: 'POST', json: statusBody },
781
+ { token: this.access_token, fallbackUrl: `${FALLBACK_API_URL}/proxy/set_proxy_statuses` },
782
+ ).catch();
783
+ }
784
+
772
785
  return this._tz.timezone;
773
786
  }
774
787
 
@@ -844,12 +857,13 @@ export class GoLogin {
844
857
  } else {
845
858
  let params = [
846
859
  `--remote-debugging-port=${remote_debugging_port}`,
847
- `--user-data-dir=${profile_path}`,
848
860
  '--password-store=basic',
849
861
  `--tz=${tz}`,
850
862
  `--lang=${this.browserLang}`,
863
+ `--window-size=${this.resolution.width},${this.resolution.height}`,
864
+ '--window-position=0,0',
865
+ `--user-data-dir=${profile_path}`,
851
866
  ];
852
-
853
867
  if (this.extensionPathsToInstall.length) {
854
868
  if (Array.isArray(this.extra_params) && this.extra_params.length) {
855
869
  this.extra_params.forEach((param, index) => {
@@ -895,34 +909,31 @@ export class GoLogin {
895
909
  }
896
910
 
897
911
  params.push(...new Set(customArgs));
898
-
899
- console.log(params);
912
+ console.log('params', params);
900
913
  const child = execFile(ORBITA_BROWSER, params, { env });
901
914
  this.processSpawned = child;
902
915
  // const child = spawn(ORBITA_BROWSER, params, { env, shell: true });
903
- child.stdout.on('data', (data) => debug(data.toString()));
916
+ child.stdout.on('error', (data) => console.log(data.toString()));
917
+ child.stderr.on('data', (data) => console.log(data.toString()));
904
918
  debug('SPAWN CMD', ORBITA_BROWSER, params.join(' '));
905
919
  }
906
920
 
907
921
  if (this.waitWebsocket) {
908
922
  debug('GETTING WS URL FROM BROWSER');
909
- const data = await requests.get(`http://127.0.0.1:${remote_debugging_port}/json/version`, { json: true, maxAttempts: 10, retryDelay: 1000 });
923
+ const data = await makeRequest(
924
+ `http://127.0.0.1:${remote_debugging_port}/json/version`,
925
+ { json: true, maxAttempts: 30, retryDelay: 1000, method: 'GET' },
926
+ );
910
927
 
911
- debug('WS IS', get(data, 'body.webSocketDebuggerUrl', ''));
928
+ debug('WS IS', get(data, 'webSocketDebuggerUrl', ''));
912
929
  this.is_active = true;
913
930
 
914
- return get(data, 'body.webSocketDebuggerUrl', '');
931
+ return { wsUrl: get(data, 'webSocketDebuggerUrl', ''), resolution: this.resolution };
915
932
  }
916
933
 
917
934
  return '';
918
935
  }
919
936
 
920
- async createStartupAndSpawnBrowser() {
921
- await this.createStartup();
922
-
923
- return this.spawnBrowser();
924
- }
925
-
926
937
  async clearProfileFiles() {
927
938
  await rimraf(join(this.tmpdir, `gologin_profile_${this.profile_id}`), () => null);
928
939
  await rimraf(join(this.tmpdir, `gologin_${this.profile_id}_upload.zip`), () => null);
@@ -974,22 +985,22 @@ export class GoLogin {
974
985
  isStorageGateway: true,
975
986
  };
976
987
 
977
- const updateResult = await requests.post(`${API_URL}/browser/features/profile/${this.profile_id}/update_after_close`, {
978
- headers: {
979
- Authorization: `Bearer ${this.access_token}`,
980
- 'User-Agent': 'gologin-api',
981
- },
988
+ const updateResult = await makeRequest(`${API_URL}/browser/features/profile/${this.profile_id}/update_after_close`, {
982
989
  json: body,
990
+ method: 'POST',
983
991
  maxAttempts: 3,
984
992
  retryDelay: 2000,
985
993
  timeout: 20 * 1000,
994
+ }, {
995
+ token: this.access_token,
996
+ fallbackUrl: `${FALLBACK_API_URL}/browser/features/profile/${this.profile_id}/update_after_close`,
986
997
  }).catch((e) => {
987
998
  console.log(e);
988
999
 
989
1000
  return e;
990
1001
  });
991
1002
 
992
- return updateResult.body;
1003
+ return updateResult;
993
1004
  }
994
1005
 
995
1006
  async stopBrowser() {
@@ -1087,26 +1098,6 @@ export class GoLogin {
1087
1098
  return fileBuff;
1088
1099
  }
1089
1100
 
1090
- async profileExists() {
1091
- const profileResponse = await requests.post(`${API_URL}/browser`, {
1092
- headers: {
1093
- 'Authorization': `Bearer ${this.access_token}`,
1094
- 'User-Agent': 'gologin-api',
1095
- },
1096
- json: {
1097
-
1098
- },
1099
- });
1100
-
1101
- if (profileResponse.statusCode !== 200) {
1102
- return false;
1103
- }
1104
-
1105
- debug('profile is', profileResponse.body);
1106
-
1107
- return true;
1108
- }
1109
-
1110
1101
  async getRandomFingerprint(options) {
1111
1102
  let os = 'lin';
1112
1103
 
@@ -1119,14 +1110,11 @@ export class GoLogin {
1119
1110
  url += '&isM1=true';
1120
1111
  }
1121
1112
 
1122
- const fingerprint = await requests.get(url, {
1123
- headers: {
1124
- 'Authorization': `Bearer ${this.access_token}`,
1125
- 'User-Agent': 'gologin-api',
1126
- },
1127
- });
1113
+ const fingerprint = await makeRequest(url, {
1114
+ method: 'GET',
1115
+ }, { token: this.access_token, fallbackUrl: `${FALLBACK_API_URL}/browser/fingerprint?os=${os}` });
1128
1116
 
1129
- return JSON.parse(fingerprint.body);
1117
+ return JSON.parse(fingerprint);
1130
1118
  }
1131
1119
 
1132
1120
  async create(options) {
@@ -1184,35 +1172,19 @@ export class GoLogin {
1184
1172
  json.navigator.userAgent = orig_user_agent;
1185
1173
  }
1186
1174
 
1187
- const response = await requests.post(`${API_URL}/browser`, {
1188
- headers: {
1189
- 'Authorization': `Bearer ${this.access_token}`,
1190
- 'User-Agent': 'gologin-api',
1191
- },
1175
+ const response = await makeRequest(`${API_URL}/browser`, {
1176
+ method: 'POST',
1192
1177
  json,
1193
- });
1194
-
1195
- if (response.statusCode === 400) {
1196
- throw new Error(`gologin failed account creation with status code, ${response.statusCode} DATA ${JSON.stringify(response.body.message)}`);
1197
- }
1198
-
1199
- if (response.statusCode === 500) {
1200
- throw new Error(`gologin failed account creation with status code, ${response.statusCode}`);
1201
- }
1178
+ }, { token: this.access_token, fallbackUrl: `${FALLBACK_API_URL}/browser` });
1202
1179
 
1203
- debug(JSON.stringify(response.body));
1204
-
1205
- return response.body.id;
1180
+ return response.id;
1206
1181
  }
1207
1182
 
1208
1183
  async delete(pid) {
1209
1184
  const profile_id = pid || this.profile_id;
1210
- await requests.delete(`${API_URL}/browser/${profile_id}`, {
1211
- headers: {
1212
- 'Authorization': `Bearer ${this.access_token}`,
1213
- 'User-Agent': 'gologin-api',
1214
- },
1215
- });
1185
+ await makeRequest(`${API_URL}/browser/${profile_id}`, {
1186
+ method: 'DELETE',
1187
+ }, { token: this.access_token, fallbackUrl: `${FALLBACK_API_URL}/browser/${profile_id}` });
1216
1188
  }
1217
1189
 
1218
1190
  async update(options) {
@@ -1230,17 +1202,14 @@ export class GoLogin {
1230
1202
  });
1231
1203
 
1232
1204
  debug('update profile', profile);
1233
- const response = await requests.put(`${API_URL}/browser/${options.id}`, {
1205
+ const response = await makeRequest(`${API_URL}/browser/${options.id}`, {
1234
1206
  json: profile,
1235
- headers: {
1236
- 'Authorization': `Bearer ${this.access_token}`,
1237
- 'User-Agent': 'gologin-api',
1238
- },
1239
- });
1207
+ method: 'PUT',
1208
+ }, { token: this.access_token, fallbackUrl: `${FALLBACK_API_URL}/browser/${options.id}` });
1240
1209
 
1241
- debug('response', JSON.stringify(response.body));
1210
+ debug('response', JSON.stringify(response));
1242
1211
 
1243
- return response.body;
1212
+ return response;
1244
1213
  }
1245
1214
 
1246
1215
  setActive(is_active) {
@@ -1285,11 +1254,7 @@ export class GoLogin {
1285
1254
  ACCESS_TOKEN: this.access_token,
1286
1255
  });
1287
1256
 
1288
- if (response.statusCode === 200) {
1289
- return response.body;
1290
- }
1291
-
1292
- return { status: 'failure', status_code: response.statusCode, body: response.body };
1257
+ return response;
1293
1258
  }
1294
1259
 
1295
1260
  async getCookies(profileId) {
@@ -1299,7 +1264,7 @@ export class GoLogin {
1299
1264
  ACCESS_TOKEN: this.access_token,
1300
1265
  });
1301
1266
 
1302
- return response.body;
1267
+ return response;
1303
1268
  }
1304
1269
 
1305
1270
  getCookiePath(defaultFilePath) {
@@ -1380,21 +1345,25 @@ export class GoLogin {
1380
1345
  }
1381
1346
 
1382
1347
  async start() {
1383
- await this.createStartup();
1384
- // await this.createBrowserExtension();
1385
- const wsUrl = await this.spawnBrowser();
1386
- this.setActive(true);
1348
+ try {
1349
+ await this.createStartup();
1350
+ const startResponse = await this.spawnBrowser();
1351
+ this.setActive(true);
1387
1352
 
1388
- return { status: 'success', wsUrl };
1353
+ return { status: 'success', wsUrl: startResponse.wsUrl, resolution: startResponse.resolution };
1354
+ } catch (error) {
1355
+ Sentry.captureException(error);
1356
+ throw error;
1357
+ }
1389
1358
  }
1390
1359
 
1391
1360
  async startLocal() {
1392
1361
  await this.createStartup(true);
1393
1362
  // await this.createBrowserExtension();
1394
- const wsUrl = await this.spawnBrowser();
1363
+ const startResponse = await this.spawnBrowser();
1395
1364
  this.setActive(true);
1396
1365
 
1397
- return { status: 'success', wsUrl };
1366
+ return { status: 'success', wsUrl: startResponse.wsUrl };
1398
1367
  }
1399
1368
 
1400
1369
  async stop() {
@@ -1412,16 +1381,18 @@ export class GoLogin {
1412
1381
  await delay(delay_ms);
1413
1382
  const url = `${remoteOrbitaUrl}/json/version`;
1414
1383
  console.log('try_count=', try_count, 'url=', url);
1415
- const response = await requests.get(url);
1384
+ const response = await makeRequest(url, {
1385
+ method: 'GET',
1386
+ });
1387
+
1416
1388
  let wsUrl = '';
1417
- console.log('response', response.body);
1418
1389
 
1419
- if (!response.body) {
1390
+ if (!response) {
1420
1391
  return wsUrl;
1421
1392
  }
1422
1393
 
1423
1394
  try {
1424
- const parsedBody = JSON.parse(response.body);
1395
+ const parsedBody = JSON.parse(response);
1425
1396
  wsUrl = parsedBody.webSocketDebuggerUrl;
1426
1397
  } catch (e) {
1427
1398
  if (try_count < 3) {
@@ -1439,16 +1410,12 @@ export class GoLogin {
1439
1410
 
1440
1411
  async stopRemote() {
1441
1412
  debug(`stopRemote ${this.profile_id}`);
1442
- const profileResponse = await requests.delete(`${API_URL}/browser/${this.profile_id}/web`, {
1443
- headers: {
1444
- 'Authorization': `Bearer ${this.access_token}`,
1445
- 'User-Agent': 'gologin-api',
1446
- },
1447
- });
1413
+ const profileResponse = await makeRequest(`${API_URL}/browser/${this.profile_id}/web`, {
1414
+ method: 'DELETE',
1415
+ }, { token: this.access_token, fallbackUrl: `${FALLBACK_API_URL}/browser/${this.profile_id}/web` });
1448
1416
 
1449
- console.log(`stopRemote ${profileResponse.body}`);
1450
- if (profileResponse.body) {
1451
- return JSON.parse(profileResponse.body);
1417
+ if (profileResponse) {
1418
+ return JSON.parse(profileResponse);
1452
1419
  }
1453
1420
  }
1454
1421
 
@@ -1476,48 +1443,37 @@ export class GoLogin {
1476
1443
  const { os, osSpec } = osInfo;
1477
1444
  const resultName = name || 'api-generated';
1478
1445
 
1479
- return requests.post(`${API_URL}/browser/quick`, {
1480
- headers: {
1481
- 'Authorization': `Bearer ${this.access_token}`,
1482
- 'User-Agent': 'gologin-api',
1483
- },
1446
+ return makeRequest(`${API_URL}/browser/quick`, {
1447
+ method: 'POST',
1484
1448
  json: {
1485
1449
  os,
1486
1450
  osSpec,
1487
1451
  name: resultName,
1488
1452
  },
1489
- })
1490
- .then(res => res.body);
1453
+ }, { token: this.access_token, fallbackUrl: `${FALLBACK_API_URL}/browser/quick` });
1491
1454
  }
1492
1455
 
1493
1456
  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
- });
1457
+ const profilesResponse = await makeRequest(`${API_URL}/browser/v2`, {
1458
+ method: 'GET',
1459
+ }, { token: this.access_token, fallbackUrl: `${FALLBACK_API_URL}/browser/v2` });
1501
1460
 
1502
1461
  if (profilesResponse.statusCode !== 200) {
1503
1462
  throw new Error('Gologin /browser response error');
1504
1463
  }
1505
1464
 
1506
- return JSON.parse(profilesResponse.body);
1465
+ return JSON.parse(profilesResponse);
1507
1466
  }
1508
1467
 
1509
1468
  async getNewFingerPrint(os) {
1510
1469
  debug('GETTING FINGERPRINT');
1511
1470
 
1512
- const fpResponse = await requests.get(`${API_URL}/browser/fingerprint?os=${os}`, {
1471
+ const fpResponse = await makeRequest(`${API_URL}/browser/fingerprint?os=${os}`, {
1513
1472
  json: true,
1514
- headers: {
1515
- 'Authorization': `Bearer ${this.access_token}`,
1516
- 'User-Agent': 'gologin-api',
1517
- },
1518
- });
1473
+ method: 'GET',
1474
+ }, { token: this.access_token, fallbackUrl: `${FALLBACK_API_URL}/browser/fingerprint?os=${os}` });
1519
1475
 
1520
- return fpResponse?.body || {};
1476
+ return fpResponse || {};
1521
1477
  }
1522
1478
  }
1523
1479
 
@@ -7,6 +7,7 @@ import { promisify } from 'util';
7
7
  import { deleteExtensionArchive, extractExtension } from '../extensions/extensions-extractor.js';
8
8
 
9
9
  export const API_URL = 'https://api.gologin.com';
10
+ export const FALLBACK_API_URL = 'https://api.gologin.co';
10
11
 
11
12
  const HOMEDIR = homedir();
12
13
  const CHROME_EXT_DIR_NAME = 'chrome-extensions';