gologin 1.0.31 → 1.0.35
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/gologin.js +133 -112
- package/package.json +3 -3
- package/selenium/gologin.py +1 -1
package/gologin.js
CHANGED
|
@@ -5,6 +5,7 @@ const fs = require('fs');
|
|
|
5
5
|
const os = require('os');
|
|
6
6
|
const util = require('util');
|
|
7
7
|
const rimraf = util.promisify(require('rimraf'));
|
|
8
|
+
const { access, unlink, writeFile, readFile } = require('fs').promises;
|
|
8
9
|
const exec = util.promisify(require('child_process').exec);
|
|
9
10
|
const { spawn, execFile } = require('child_process');
|
|
10
11
|
const FormData = require('form-data');
|
|
@@ -12,7 +13,7 @@ const ProxyAgent = require('simple-proxy-agent');
|
|
|
12
13
|
const decompress = require('decompress');
|
|
13
14
|
const decompressUnzip = require('decompress-unzip');
|
|
14
15
|
const path = require('path');
|
|
15
|
-
const
|
|
16
|
+
const zipdir = require('zip-dir');
|
|
16
17
|
|
|
17
18
|
const BrowserChecker = require('./browser-checker');
|
|
18
19
|
const { BrowserUserDataManager } = require('./browser-user-data-manager');
|
|
@@ -54,7 +55,7 @@ class GoLogin {
|
|
|
54
55
|
this.tmpdir = options.tmpdir;
|
|
55
56
|
if (!fs.existsSync(this.tmpdir)) {
|
|
56
57
|
debug('making tmpdir', this.tmpdir);
|
|
57
|
-
|
|
58
|
+
fs.mkdirSync(this.tmpdir, { recursive: true })
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
|
|
@@ -99,7 +100,7 @@ class GoLogin {
|
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
async profiles() {
|
|
102
|
-
const profilesResponse = await requests.get(`${API_URL}/browser
|
|
103
|
+
const profilesResponse = await requests.get(`${API_URL}/browser/v2`, {
|
|
103
104
|
headers: {
|
|
104
105
|
'Authorization': `Bearer ${this.access_token}`,
|
|
105
106
|
'User-Agent': 'gologin-api',
|
|
@@ -127,7 +128,7 @@ class GoLogin {
|
|
|
127
128
|
throw new Error(`Gologin /browser/${id} response error ${profileResponse.statusCode} INVALID TOKEN OR PROFILE NOT FOUND`);
|
|
128
129
|
}
|
|
129
130
|
|
|
130
|
-
if(profileResponse.statusCode
|
|
131
|
+
if (profileResponse.statusCode === 401) {
|
|
131
132
|
throw new Error("invalid token");
|
|
132
133
|
}
|
|
133
134
|
|
|
@@ -135,77 +136,86 @@ class GoLogin {
|
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
async emptyProfile() {
|
|
138
|
-
|
|
139
|
+
return readFile(path.resolve(__dirname, 'gologin_zeroprofile.b64')).then(res => res.toString());
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
async getProfileS3(s3path) {
|
|
143
|
+
if (!s3path) {
|
|
144
|
+
throw new Error('s3path not found');
|
|
145
|
+
}
|
|
146
|
+
|
|
142
147
|
const token = this.access_token;
|
|
143
148
|
debug('getProfileS3 token=', token, 'profile=', this.profile_id, 's3path=', s3path);
|
|
144
|
-
if (s3path) { //загрузка профиля из публичного бакета s3 быстрее
|
|
145
|
-
const s3url = `https://gprofiles.gologin.com/${s3path}`.replace(/\s+/mg, '+');
|
|
146
|
-
debug('loading profile from public s3 bucket, url=', s3url);
|
|
147
|
-
const profileResponse = await requests.get(s3url, {
|
|
148
|
-
encoding: null
|
|
149
|
-
});
|
|
150
|
-
if (profileResponse.statusCode !== 200) {
|
|
151
|
-
debug(`Gologin S3 BUCKET ${s3url} response error ${profileResponse.statusCode} - use empty`);
|
|
152
|
-
return '';
|
|
153
|
-
}
|
|
154
|
-
return Buffer.from(profileResponse.body);
|
|
155
|
-
}
|
|
156
149
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
'Authorization': `Bearer ${token}`,
|
|
161
|
-
},
|
|
150
|
+
const s3url = `https://gprofiles.gologin.com/${s3path}`.replace(/\s+/mg, '+');
|
|
151
|
+
debug('loading profile from public s3 bucket, url=', s3url);
|
|
152
|
+
const profileResponse = await requests.get(s3url, {
|
|
162
153
|
encoding: null
|
|
163
154
|
});
|
|
155
|
+
|
|
164
156
|
if (profileResponse.statusCode !== 200) {
|
|
165
|
-
debug(`Gologin
|
|
157
|
+
debug(`Gologin S3 BUCKET ${s3url} response error ${profileResponse.statusCode} - use empty`);
|
|
166
158
|
return '';
|
|
167
159
|
}
|
|
160
|
+
|
|
168
161
|
return Buffer.from(profileResponse.body);
|
|
169
162
|
}
|
|
170
163
|
|
|
171
|
-
async postFile(fileName,
|
|
172
|
-
debug('POSTING FILE',
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
164
|
+
async postFile(fileName, fileBuff) {
|
|
165
|
+
debug('POSTING FILE', fileBuff.length);
|
|
166
|
+
debug('Getting signed URL for S3');
|
|
167
|
+
const apiUrl = `${API_URL}/browser/${this.profile_id}/storage-signature`;
|
|
168
|
+
|
|
169
|
+
const signedUrl = await requests.get(apiUrl, {
|
|
170
|
+
headers: {
|
|
171
|
+
Authorization: `Bearer ${this.access_token}`,
|
|
172
|
+
'user-agent': 'gologin-api',
|
|
173
|
+
},
|
|
174
|
+
maxAttempts: 3,
|
|
175
|
+
retryDelay: 2000,
|
|
176
|
+
timeout: 10 * 1000,
|
|
177
|
+
fullResponse: false,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const [uploadedProfileUrl] = signedUrl.split('?');
|
|
181
|
+
|
|
182
|
+
console.log('Uploading profile by signed URL to S3');
|
|
183
|
+
const bodyBufferBiteLength = Buffer.byteLength(fileBuff);
|
|
184
|
+
console.log('BUFFER SIZE', bodyBufferBiteLength);
|
|
185
|
+
|
|
186
|
+
await requests.put(signedUrl, {
|
|
187
|
+
headers: {
|
|
188
|
+
'Content-Type': 'application/zip',
|
|
189
|
+
'Content-Length': bodyBufferBiteLength,
|
|
190
|
+
},
|
|
191
|
+
body: fileBuff,
|
|
192
|
+
maxBodyLength: Infinity,
|
|
193
|
+
maxContentLength: Infinity,
|
|
194
|
+
maxAttempts: 3,
|
|
195
|
+
retryDelay: 2000,
|
|
196
|
+
timeout: 30 * 1000,
|
|
197
|
+
fullResponse: false,
|
|
203
198
|
});
|
|
199
|
+
|
|
200
|
+
const uploadedProfileMetadata = await requests.head(uploadedProfileUrl, {
|
|
201
|
+
maxAttempts: 3,
|
|
202
|
+
retryDelay: 2000,
|
|
203
|
+
timeout: 10 * 1000,
|
|
204
|
+
fullResponse: true,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const uploadedFileLength = +uploadedProfileMetadata.headers['content-length'];
|
|
208
|
+
if (uploadedFileLength !== bodyBufferBiteLength) {
|
|
209
|
+
console.log('Uploaded file is incorrect. Retry with China File size:', uploadedFileLength);
|
|
210
|
+
throw new Error('Uploaded file is incorrect. Retry with China File size: ' + uploadedFileLength);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
console.log('Profile has been uploaded to S3 successfully');
|
|
204
214
|
}
|
|
205
215
|
|
|
206
216
|
async emptyProfileFolder() {
|
|
207
217
|
debug('get emptyProfileFolder');
|
|
208
|
-
const profile =
|
|
218
|
+
const profile = await readFile(path.resolve(__dirname, 'gologin_zeroprofile.zip'));
|
|
209
219
|
debug('emptyProfileFolder LENGTH ::', profile.length);
|
|
210
220
|
return profile;
|
|
211
221
|
}
|
|
@@ -246,9 +256,8 @@ class GoLogin {
|
|
|
246
256
|
.then(() => {
|
|
247
257
|
debug('extraction done');
|
|
248
258
|
debug('create uid.json');
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
return extPath;
|
|
259
|
+
return writeFile(path.join(extPath, 'uid.json'), JSON.stringify({ uid: that.profile_id }, null, 2))
|
|
260
|
+
.then(() => extPath);
|
|
252
261
|
})
|
|
253
262
|
.catch(async (e) => {
|
|
254
263
|
debug('orbita extension error', e);
|
|
@@ -299,19 +308,21 @@ class GoLogin {
|
|
|
299
308
|
height: parseInt(screenHeight, 10),
|
|
300
309
|
};
|
|
301
310
|
|
|
302
|
-
|
|
311
|
+
const profileZipExists = await access(this.profile_zip_path).then(() => true).catch(() => false);
|
|
312
|
+
if (!(local && profileZipExists)) {
|
|
303
313
|
try {
|
|
304
314
|
profile_folder = await this.getProfileS3(_.get(profile, 's3Path', ''));
|
|
305
315
|
}
|
|
306
316
|
catch (e) {
|
|
307
317
|
debug('Cannot get profile - using empty', e);
|
|
308
318
|
}
|
|
319
|
+
|
|
309
320
|
debug('FILE READY', this.profile_zip_path);
|
|
310
321
|
if (!profile_folder.length) {
|
|
311
322
|
profile_folder = await this.emptyProfileFolder();
|
|
312
323
|
}
|
|
313
|
-
|
|
314
|
-
|
|
324
|
+
|
|
325
|
+
await writeFile(this.profile_zip_path, profile_folder);
|
|
315
326
|
|
|
316
327
|
debug('PROFILE LENGTH', profile_folder.length);
|
|
317
328
|
} else {
|
|
@@ -323,20 +334,23 @@ class GoLogin {
|
|
|
323
334
|
await this.extractProfile(profilePath, this.profile_zip_path);
|
|
324
335
|
debug('extraction done');
|
|
325
336
|
|
|
326
|
-
|
|
337
|
+
const singletonLockPath = path.join(profilePath, 'SingletonLock');
|
|
338
|
+
const singletonLockExists = await access(singletonLockPath).then(() => true).catch(() => false);
|
|
339
|
+
if (singletonLockExists) {
|
|
327
340
|
debug('removing SingletonLock');
|
|
328
|
-
|
|
341
|
+
await unlink(singletonLockPath);
|
|
329
342
|
debug('SingletonLock removed');
|
|
330
343
|
}
|
|
331
344
|
|
|
332
345
|
const pref_file_name = path.join(profilePath, 'Default', 'Preferences');
|
|
333
346
|
debug('reading', pref_file_name);
|
|
334
347
|
|
|
335
|
-
|
|
348
|
+
const prefFileExists = await access(pref_file_name).then(() => true).catch(() => false);
|
|
349
|
+
if (!prefFileExists) {
|
|
336
350
|
debug('Preferences file not exists waiting', pref_file_name);
|
|
337
351
|
}
|
|
338
352
|
|
|
339
|
-
const preferences_raw =
|
|
353
|
+
const preferences_raw = await readFile(pref_file_name);
|
|
340
354
|
let preferences = JSON.parse(preferences_raw.toString());
|
|
341
355
|
let proxy = _.get(profile, 'proxy');
|
|
342
356
|
let name = _.get(profile, 'name');
|
|
@@ -436,7 +450,11 @@ class GoLogin {
|
|
|
436
450
|
await BrowserUserDataManager.composeFonts(families, profilePath, this.differentOs);
|
|
437
451
|
}
|
|
438
452
|
|
|
439
|
-
|
|
453
|
+
const [languages] = this.language.split(';');
|
|
454
|
+
preferences.gologin.langHeader = gologin.language;
|
|
455
|
+
preferences.gologin.languages = languages;
|
|
456
|
+
|
|
457
|
+
await writeFile(path.join(profilePath, 'Default', 'Preferences'), JSON.stringify(_.merge(preferences, {
|
|
440
458
|
gologin
|
|
441
459
|
})));
|
|
442
460
|
|
|
@@ -449,20 +467,23 @@ class GoLogin {
|
|
|
449
467
|
}
|
|
450
468
|
|
|
451
469
|
async commitProfile() {
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
470
|
+
const dataBuff = await this.getProfileDataToUpdate();
|
|
471
|
+
|
|
472
|
+
debug('begin updating', dataBuff.length);
|
|
473
|
+
if (!dataBuff.length) {
|
|
455
474
|
debug('WARN: profile zip data empty - SKIPPING PROFILE COMMIT');
|
|
456
475
|
|
|
457
476
|
return;
|
|
458
477
|
}
|
|
478
|
+
|
|
459
479
|
try {
|
|
460
480
|
debug('Patching profile');
|
|
461
|
-
await this.postFile('profile',
|
|
481
|
+
await this.postFile('profile', dataBuff);
|
|
462
482
|
}
|
|
463
483
|
catch (e) {
|
|
464
484
|
debug('CANNOT COMMIT PROFILE', e);
|
|
465
485
|
}
|
|
486
|
+
|
|
466
487
|
debug('COMMIT COMPLETED');
|
|
467
488
|
}
|
|
468
489
|
|
|
@@ -482,16 +503,16 @@ class GoLogin {
|
|
|
482
503
|
|
|
483
504
|
async checkPortAvailable(port) {
|
|
484
505
|
debug('CHECKING PORT AVAILABLE', port);
|
|
506
|
+
|
|
485
507
|
try {
|
|
486
508
|
const { stdout, stderr } = await exec(`lsof -i:${port}`);
|
|
487
|
-
if (
|
|
488
|
-
stdout && stdout.match(/LISTEN/gmi)
|
|
489
|
-
) {
|
|
509
|
+
if (stdout && stdout.match(/LISTEN/gmi)) {
|
|
490
510
|
debug(`PORT ${port} IS BUSY`)
|
|
491
511
|
return false;
|
|
492
512
|
}
|
|
493
|
-
} catch (e) {
|
|
513
|
+
} catch (e) {}
|
|
494
514
|
debug(`PORT ${port} IS OPEN`);
|
|
515
|
+
|
|
495
516
|
return true;
|
|
496
517
|
}
|
|
497
518
|
|
|
@@ -507,7 +528,7 @@ class GoLogin {
|
|
|
507
528
|
|
|
508
529
|
async getTimeZone(proxy) {
|
|
509
530
|
debug('getting timeZone proxy=', proxy);
|
|
510
|
-
if(this.timezone){
|
|
531
|
+
if (this.timezone) {
|
|
511
532
|
debug('getTimeZone from options', this.timezone);
|
|
512
533
|
this._tz = this.timezone;
|
|
513
534
|
return this._tz.timezone;
|
|
@@ -604,7 +625,7 @@ class GoLogin {
|
|
|
604
625
|
|
|
605
626
|
async spawnBrowser() {
|
|
606
627
|
let remote_debugging_port = this.remote_debugging_port;
|
|
607
|
-
if(!remote_debugging_port){
|
|
628
|
+
if (!remote_debugging_port) {
|
|
608
629
|
remote_debugging_port = await this.getRandomPort();
|
|
609
630
|
}
|
|
610
631
|
|
|
@@ -706,7 +727,9 @@ class GoLogin {
|
|
|
706
727
|
if (this.is_stopping) {
|
|
707
728
|
return true;
|
|
708
729
|
}
|
|
709
|
-
const is_posting = options.
|
|
730
|
+
const is_posting = options.posting ||
|
|
731
|
+
options.postings || // backward compability
|
|
732
|
+
false;
|
|
710
733
|
|
|
711
734
|
if (this.uploadCookiesToServer) {
|
|
712
735
|
await this.uploadProfileCookiesToServer();
|
|
@@ -782,34 +805,31 @@ class GoLogin {
|
|
|
782
805
|
|
|
783
806
|
async getProfileDataToUpdate() {
|
|
784
807
|
const zipPath = path.join(this.tmpdir, `gologin_${this.profile_id}_upload.zip`);
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
catch (e) {
|
|
808
|
+
const zipExists = await access(zipPath).then(() => true).catch(() => false);
|
|
809
|
+
if (zipExists) {
|
|
810
|
+
await unlink(zipPath);
|
|
789
811
|
}
|
|
812
|
+
|
|
790
813
|
await this.sanitizeProfile();
|
|
791
814
|
debug('profile sanitized');
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
debug('saveprofile error', e);
|
|
811
|
-
return '';
|
|
812
|
-
}
|
|
815
|
+
|
|
816
|
+
const profilePath = this.profilePath();
|
|
817
|
+
const fileBuff = await new Promise((resolve, reject) => zipdir(profilePath,
|
|
818
|
+
{
|
|
819
|
+
saveTo: zipPath,
|
|
820
|
+
filter: (path) => !/RunningChromeVersion/.test(path),
|
|
821
|
+
}, (err, buffer) => {
|
|
822
|
+
if (err) {
|
|
823
|
+
reject(err);
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
resolve(buffer);
|
|
828
|
+
})
|
|
829
|
+
)
|
|
830
|
+
|
|
831
|
+
debug('PROFILE ZIP CREATED', profilePath, zipPath);
|
|
832
|
+
return fileBuff;
|
|
813
833
|
}
|
|
814
834
|
|
|
815
835
|
async profileExists() {
|
|
@@ -853,11 +873,11 @@ class GoLogin {
|
|
|
853
873
|
const fingerprint = await this.getRandomFingerprint(options);
|
|
854
874
|
debug("fingerprint=", fingerprint)
|
|
855
875
|
|
|
856
|
-
if(fingerprint.statusCode
|
|
876
|
+
if (fingerprint.statusCode === 500) {
|
|
857
877
|
throw new Error("no valid random fingerprint check os param");
|
|
858
878
|
}
|
|
859
879
|
|
|
860
|
-
if(fingerprint.statusCode
|
|
880
|
+
if (fingerprint.statusCode === 401) {
|
|
861
881
|
throw new Error("invalid token");
|
|
862
882
|
}
|
|
863
883
|
|
|
@@ -887,7 +907,7 @@ class GoLogin {
|
|
|
887
907
|
let user_agent = options.navigator?.userAgent;
|
|
888
908
|
let orig_user_agent = json.navigator.userAgent;
|
|
889
909
|
Object.keys(options).map((e)=>{ json[e] = options[e] });
|
|
890
|
-
if(user_agent
|
|
910
|
+
if (user_agent === 'random') {
|
|
891
911
|
json.navigator.userAgent = orig_user_agent;
|
|
892
912
|
}
|
|
893
913
|
// console.log('profileOptions', json);
|
|
@@ -900,11 +920,11 @@ class GoLogin {
|
|
|
900
920
|
json,
|
|
901
921
|
});
|
|
902
922
|
|
|
903
|
-
if(response.body.statusCode
|
|
923
|
+
if (response.body.statusCode === 400) {
|
|
904
924
|
throw new Error(`gologin failed account creation with status code, ${data.statusCode} DATA ${JSON.stringify(response.body.message)}`);
|
|
905
925
|
}
|
|
906
926
|
|
|
907
|
-
if(response.body.statusCode
|
|
927
|
+
if (response.body.statusCode === 500) {
|
|
908
928
|
throw new Error(`gologin failed account creation with status code, ${data.statusCode}`);
|
|
909
929
|
}
|
|
910
930
|
debug(JSON.stringify(response.body));
|
|
@@ -1045,7 +1065,8 @@ class GoLogin {
|
|
|
1045
1065
|
|
|
1046
1066
|
const ORBITA_BROWSER = this.executablePath || this.browserChecker.getOrbitaPath;
|
|
1047
1067
|
|
|
1048
|
-
|
|
1068
|
+
const orbitaBrowserExists = await access(ORBITA_BROWSER).then(() => true).catch(() => false);
|
|
1069
|
+
if (!orbitaBrowserExists) {
|
|
1049
1070
|
throw new Error(`Orbita browser is not exists on path ${ORBITA_BROWSER}, check executablePath param`);
|
|
1050
1071
|
}
|
|
1051
1072
|
|
|
@@ -1071,12 +1092,12 @@ class GoLogin {
|
|
|
1071
1092
|
return this.stopRemote();
|
|
1072
1093
|
}
|
|
1073
1094
|
|
|
1074
|
-
await this.stopAndCommit({ posting:
|
|
1095
|
+
await this.stopAndCommit({ posting: true }, false);
|
|
1075
1096
|
}
|
|
1076
1097
|
|
|
1077
1098
|
async stopLocal(options) {
|
|
1078
1099
|
const opts = options || { posting: false };
|
|
1079
|
-
await this.stopAndCommit(
|
|
1100
|
+
await this.stopAndCommit(opts, true);
|
|
1080
1101
|
}
|
|
1081
1102
|
|
|
1082
1103
|
async waitDebuggingUrl(delay_ms, try_count=0) {
|
|
@@ -1113,7 +1134,7 @@ class GoLogin {
|
|
|
1113
1134
|
}
|
|
1114
1135
|
});
|
|
1115
1136
|
|
|
1116
|
-
if(profileResponse.statusCode
|
|
1137
|
+
if (profileResponse.statusCode === 401){
|
|
1117
1138
|
throw new Error("invalid token");
|
|
1118
1139
|
}
|
|
1119
1140
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gologin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.35",
|
|
4
4
|
"description": "A high-level API to control Orbita browser over GoLogin API",
|
|
5
5
|
"main": "./gologin.js",
|
|
6
6
|
"repository": {
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"requestretry": "^4.1.0",
|
|
27
27
|
"rimraf": "^3.0.2",
|
|
28
28
|
"selenium-webdriver": "^4.0.0-alpha.7",
|
|
29
|
-
"shelljs": "^0.8.4",
|
|
30
29
|
"simple-proxy-agent": "^1.1.0",
|
|
31
30
|
"sqlite": "^4.0.23",
|
|
32
|
-
"sqlite3": "^5.0.2"
|
|
31
|
+
"sqlite3": "^5.0.2",
|
|
32
|
+
"zip-dir": "^2.0.0"
|
|
33
33
|
},
|
|
34
34
|
"bugs": {
|
|
35
35
|
"url": "https://github.com/gologinapp/gologin/issues"
|
package/selenium/gologin.py
CHANGED
|
@@ -371,7 +371,7 @@ class GoLogin(object):
|
|
|
371
371
|
return json.loads(requests.get(API_URL + '/browser/fingerprint?os=' + os_type, headers=self.headers()).content.decode('utf-8'))
|
|
372
372
|
|
|
373
373
|
def profiles(self):
|
|
374
|
-
return json.loads(requests.get(API_URL + '/browser/', headers=self.headers()).content.decode('utf-8'))
|
|
374
|
+
return json.loads(requests.get(API_URL + '/browser/v2', headers=self.headers()).content.decode('utf-8'))
|
|
375
375
|
|
|
376
376
|
def create(self, options={}):
|
|
377
377
|
profile_options = self.getRandomFingerprint(options)
|