channel-worker 1.3.3 → 1.3.4
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/lib/nst-manager.js +45 -68
- package/package.json +1 -2
package/lib/nst-manager.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
let NstBrowserV2;
|
|
2
|
-
try {
|
|
3
|
-
NstBrowserV2 = require('nstbrowser-sdk-node').NstBrowserV2;
|
|
4
|
-
} catch {
|
|
5
|
-
// SDK not installed
|
|
6
|
-
}
|
|
7
|
-
|
|
8
1
|
class NstManager {
|
|
9
2
|
constructor(apiKey, options = {}) {
|
|
10
|
-
if (!NstBrowserV2) {
|
|
11
|
-
throw new Error('nstbrowser-sdk-node not installed. Run: npm install -g nstbrowser-sdk-node');
|
|
12
|
-
}
|
|
13
3
|
this.apiKey = apiKey;
|
|
14
|
-
this.
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
this.baseUrl = options.apiAddress || 'http://localhost:8848/api/v2';
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
async api(path, options = {}) {
|
|
8
|
+
const url = path.startsWith('http') ? path : `${this.baseUrl}${path}`;
|
|
9
|
+
const res = await fetch(url, {
|
|
10
|
+
...options,
|
|
11
|
+
headers: {
|
|
12
|
+
'x-api-key': this.apiKey,
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
...options.headers,
|
|
15
|
+
},
|
|
17
16
|
});
|
|
17
|
+
return res.json();
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// Get all running browsers
|
|
21
21
|
async getRunningBrowsers() {
|
|
22
22
|
try {
|
|
23
|
-
const res = await this.
|
|
23
|
+
const res = await this.api('/browsers/running');
|
|
24
24
|
return res?.data || [];
|
|
25
25
|
} catch (err) {
|
|
26
26
|
console.error(`[nst] Error getting running browsers:`, err.message);
|
|
@@ -37,36 +37,19 @@ class NstManager {
|
|
|
37
37
|
// Find profile by name, return profileId
|
|
38
38
|
async findProfile(name) {
|
|
39
39
|
try {
|
|
40
|
-
// Try SDK first
|
|
41
|
-
const res = await this.client.profiles().getProfiles({ keyword: name });
|
|
42
|
-
let profiles = [];
|
|
43
|
-
if (res?.data?.docs && Array.isArray(res.data.docs)) {
|
|
44
|
-
profiles = res.data.docs;
|
|
45
|
-
} else if (Array.isArray(res?.data)) {
|
|
46
|
-
profiles = res.data;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const match = profiles.find(p => p.name?.toLowerCase() === name.toLowerCase());
|
|
50
|
-
if (match) return match.profileId || match._id;
|
|
51
|
-
|
|
52
|
-
// Fallback: fetch ALL profiles via local API (paginate if needed)
|
|
53
40
|
let allProfiles = [];
|
|
54
41
|
let page = 1;
|
|
55
42
|
while (true) {
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
});
|
|
59
|
-
const rawData = await rawRes.json();
|
|
60
|
-
const docs = rawData?.data?.docs || rawData?.data || [];
|
|
43
|
+
const res = await this.api(`/profiles/?keyword=${encodeURIComponent(name)}&page=${page}&limit=100`);
|
|
44
|
+
const docs = res?.data?.docs || res?.data || [];
|
|
61
45
|
allProfiles = allProfiles.concat(docs);
|
|
62
|
-
const totalPages =
|
|
46
|
+
const totalPages = res?.data?.totalPage || res?.data?.totalPages || 1;
|
|
63
47
|
if (page >= totalPages || docs.length === 0) break;
|
|
64
48
|
page++;
|
|
65
49
|
}
|
|
66
|
-
console.log(`[nst]
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
69
|
-
|
|
50
|
+
console.log(`[nst] Search for "${name}": found ${allProfiles.length} profiles [${allProfiles.map(p => p.name).join(', ')}]`);
|
|
51
|
+
const match = allProfiles.find(p => p.name?.toLowerCase() === name.toLowerCase());
|
|
52
|
+
if (match) return match.profileId || match._id;
|
|
70
53
|
return null;
|
|
71
54
|
} catch (err) {
|
|
72
55
|
console.error(`[nst] Error finding profile "${name}":`, err.message);
|
|
@@ -83,22 +66,19 @@ class NstManager {
|
|
|
83
66
|
}
|
|
84
67
|
|
|
85
68
|
console.log(`[nst] WARNING: Profile "${name}" NOT FOUND — creating new profile...`);
|
|
86
|
-
const res = await this.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
canvas: 'Noise',
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
69
|
+
const res = await this.api('/profiles', {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
body: JSON.stringify({
|
|
72
|
+
name,
|
|
73
|
+
platform: 'Windows',
|
|
74
|
+
kernelMilestone: '132',
|
|
75
|
+
fingerprint: {
|
|
76
|
+
flags: { audio: 'Noise', canvas: 'Noise', fonts: 'Masked', gpu: 'Allow', webgl: 'Noise' },
|
|
77
|
+
hardwareConcurrency: 8,
|
|
78
|
+
deviceMemory: 8,
|
|
79
|
+
language: 'en-US',
|
|
97
80
|
},
|
|
98
|
-
|
|
99
|
-
deviceMemory: 8,
|
|
100
|
-
language: 'en-US',
|
|
101
|
-
},
|
|
81
|
+
}),
|
|
102
82
|
});
|
|
103
83
|
|
|
104
84
|
const profileId = res?.data?.profileId || res?.data?._id;
|
|
@@ -112,7 +92,10 @@ class NstManager {
|
|
|
112
92
|
async setProxy(profileId, proxyUrl) {
|
|
113
93
|
if (!proxyUrl) return;
|
|
114
94
|
console.log(`[nst] Setting proxy for ${profileId}: ${proxyUrl}`);
|
|
115
|
-
await this.
|
|
95
|
+
await this.api(`/profiles/${profileId}/proxy`, {
|
|
96
|
+
method: 'PATCH',
|
|
97
|
+
body: JSON.stringify({ url: proxyUrl }),
|
|
98
|
+
});
|
|
116
99
|
console.log(`[nst] Proxy set`);
|
|
117
100
|
}
|
|
118
101
|
|
|
@@ -123,15 +106,15 @@ class NstManager {
|
|
|
123
106
|
profileId = await this.ensureProfile(profileIdOrName);
|
|
124
107
|
}
|
|
125
108
|
|
|
126
|
-
// If already running, skip
|
|
109
|
+
// If already running, skip
|
|
127
110
|
if (await this.isProfileRunning(profileId)) {
|
|
128
111
|
console.log(`[nst] Profile ${profileId} already running — skipping`);
|
|
129
112
|
return { profileId, alreadyRunning: true };
|
|
130
113
|
}
|
|
131
114
|
|
|
132
|
-
//
|
|
115
|
+
// Update language to en-US
|
|
133
116
|
try {
|
|
134
|
-
const res = await fetch(
|
|
117
|
+
const res = await fetch(`${this.baseUrl}/profiles/${profileId}`, {
|
|
135
118
|
method: 'PATCH',
|
|
136
119
|
headers: { 'Content-Type': 'application/json', 'x-api-key': this.apiKey },
|
|
137
120
|
body: JSON.stringify({ fingerprint: { language: 'en-US' } }),
|
|
@@ -149,12 +132,10 @@ class NstManager {
|
|
|
149
132
|
const connectConfig = {
|
|
150
133
|
headless: false,
|
|
151
134
|
autoClose: false,
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
'--lang': 'en-US',
|
|
157
|
-
'--disable-features': 'Translate',
|
|
135
|
+
args: {
|
|
136
|
+
'--lang': 'en-US',
|
|
137
|
+
'--disable-features': 'Translate',
|
|
138
|
+
},
|
|
158
139
|
};
|
|
159
140
|
|
|
160
141
|
if (options.extensionPath) {
|
|
@@ -164,11 +145,7 @@ class NstManager {
|
|
|
164
145
|
}
|
|
165
146
|
|
|
166
147
|
console.log(`[nst] Connecting browser for profile: ${profileId}`);
|
|
167
|
-
|
|
168
|
-
// SDK uses axios which serializes nested objects as config[key]=value
|
|
169
|
-
// But Nstbrowser API expects ?config=<JSON-string>
|
|
170
|
-
// Workaround: call the API directly with fetch instead of SDK
|
|
171
|
-
const apiUrl = `http://localhost:8848/api/v2/connect/${profileId}?config=${encodeURIComponent(JSON.stringify(connectConfig))}`;
|
|
148
|
+
const apiUrl = `${this.baseUrl}/connect/${profileId}?config=${encodeURIComponent(JSON.stringify(connectConfig))}`;
|
|
172
149
|
const rawRes = await fetch(apiUrl, { headers: { 'x-api-key': this.apiKey } });
|
|
173
150
|
const res = await rawRes.json();
|
|
174
151
|
if (res.err) throw new Error(res.msg || 'Failed to connect browser');
|
|
@@ -186,7 +163,7 @@ class NstManager {
|
|
|
186
163
|
}
|
|
187
164
|
|
|
188
165
|
console.log(`[nst] Stopping browser for profile: ${profileId}`);
|
|
189
|
-
await this.
|
|
166
|
+
await this.api(`/browsers/${profileId}/stop`, { method: 'PUT' });
|
|
190
167
|
console.log(`[nst] Browser stopped`);
|
|
191
168
|
}
|
|
192
169
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "channel-worker",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "Channel Manager worker daemon — runs on remote machines to execute video pipeline jobs",
|
|
5
5
|
"main": "lib/daemon.js",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"node-fetch": "^3.3.2",
|
|
19
|
-
"nstbrowser-sdk-node": "^0.1.1",
|
|
20
19
|
"ws": "^8.18.0"
|
|
21
20
|
},
|
|
22
21
|
"engines": {
|