channel-worker 1.6.3 → 1.6.5
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/api-client.js +1 -1
- package/lib/command-poller.js +80 -0
- package/lib/nst-manager.js +4 -3
- package/package.json +1 -1
package/lib/api-client.js
CHANGED
|
@@ -65,7 +65,7 @@ class ApiClient {
|
|
|
65
65
|
|
|
66
66
|
// Commands
|
|
67
67
|
async getNextCommand(workerId) {
|
|
68
|
-
const workerTypes = 'launch_profile,close_profile,save_file,set_thumbnail,set_tags,set_file_input,click_and_upload,type_text,verify_logins,update_extension,sync_youtube_stats,restart_worker';
|
|
68
|
+
const workerTypes = 'launch_profile,close_profile,launch_veo3_profile,save_file,set_thumbnail,set_tags,set_file_input,click_and_upload,type_text,verify_logins,update_extension,sync_youtube_stats,restart_worker';
|
|
69
69
|
return this.request('GET', `/workers/commands?worker_id=${workerId}&types=${encodeURIComponent(workerTypes)}`);
|
|
70
70
|
}
|
|
71
71
|
|
package/lib/command-poller.js
CHANGED
|
@@ -75,6 +75,9 @@ class CommandPoller {
|
|
|
75
75
|
case 'restart_worker':
|
|
76
76
|
await this.handleRestartWorker(command);
|
|
77
77
|
break;
|
|
78
|
+
case 'launch_veo3_profile':
|
|
79
|
+
await this.handleLaunchVeo3Profile(command);
|
|
80
|
+
break;
|
|
78
81
|
default:
|
|
79
82
|
// Other commands (scan_facebook_pages, etc.) handled by extension
|
|
80
83
|
console.log(`[commands] Skipping ${command.type} — handled by extension`);
|
|
@@ -167,6 +170,83 @@ class CommandPoller {
|
|
|
167
170
|
}
|
|
168
171
|
}
|
|
169
172
|
|
|
173
|
+
async handleLaunchVeo3Profile(command) {
|
|
174
|
+
const { nst_profile_id, name, veo3_worker_id, os, proxy } = command.payload || {};
|
|
175
|
+
console.log(`[commands] Launching Veo3 profile: ${nst_profile_id} (${name}) os=${os || 'windows'}`);
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
if (!this.nst) {
|
|
179
|
+
const apiKey = await this.api.getSetting('nst_api_key');
|
|
180
|
+
if (apiKey) {
|
|
181
|
+
this.nst = new NstManager(apiKey);
|
|
182
|
+
} else {
|
|
183
|
+
throw new Error('Nstbrowser API key not configured.');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Auto-create Nstbrowser profile if not exists
|
|
188
|
+
await this.nst.ensureProfile(nst_profile_id, { os: os || 'windows' });
|
|
189
|
+
|
|
190
|
+
// Use Content Creator extension path (separate from channel-manager-ext)
|
|
191
|
+
const baseExtPath = this.config.content_creator_ext_path || '';
|
|
192
|
+
if (!baseExtPath) throw new Error('content_creator_ext_path not configured in worker config.');
|
|
193
|
+
|
|
194
|
+
let extensionPath = baseExtPath;
|
|
195
|
+
|
|
196
|
+
// Create unique extension dir per profile
|
|
197
|
+
if (nst_profile_id) {
|
|
198
|
+
const fs = require('fs');
|
|
199
|
+
const path = require('path');
|
|
200
|
+
const ts = Date.now();
|
|
201
|
+
const uniqueExtPath = baseExtPath + '-' + nst_profile_id + '-' + ts;
|
|
202
|
+
try {
|
|
203
|
+
fs.mkdirSync(uniqueExtPath, { recursive: true });
|
|
204
|
+
const files = fs.readdirSync(baseExtPath);
|
|
205
|
+
for (const f of files) {
|
|
206
|
+
const src = path.join(baseExtPath, f);
|
|
207
|
+
if (fs.statSync(src).isFile()) fs.copyFileSync(src, path.join(uniqueExtPath, f));
|
|
208
|
+
}
|
|
209
|
+
// Write Veo3-specific config.json
|
|
210
|
+
fs.writeFileSync(path.join(uniqueExtPath, 'config.json'), JSON.stringify({
|
|
211
|
+
channelManagerApi: 'https://api.channel.tunasm.art',
|
|
212
|
+
profileId: nst_profile_id,
|
|
213
|
+
workerToken: this.config.worker_token || '',
|
|
214
|
+
workerType: 'veo3',
|
|
215
|
+
}));
|
|
216
|
+
extensionPath = uniqueExtPath;
|
|
217
|
+
console.log(`[commands] Veo3 ext dir: ${uniqueExtPath}`);
|
|
218
|
+
|
|
219
|
+
// Cleanup old dirs
|
|
220
|
+
const parent = path.dirname(baseExtPath);
|
|
221
|
+
const baseName = path.basename(baseExtPath);
|
|
222
|
+
const oldDirs = fs.readdirSync(parent)
|
|
223
|
+
.filter(d => d.startsWith(baseName + '-' + nst_profile_id) && d !== path.basename(uniqueExtPath))
|
|
224
|
+
.map(d => path.join(parent, d))
|
|
225
|
+
.filter(d => { try { return fs.statSync(d).isDirectory(); } catch { return false; } });
|
|
226
|
+
for (const d of oldDirs) {
|
|
227
|
+
try { fs.rmSync(d, { recursive: true }); } catch {}
|
|
228
|
+
}
|
|
229
|
+
} catch (e) {
|
|
230
|
+
console.warn(`[commands] Unique Veo3 ext dir failed: ${e.message}, using base`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const result = await this.nst.launchProfile(nst_profile_id, { proxy: proxy || null, extensionPath });
|
|
235
|
+
console.log(`[commands] Veo3 profile ${nst_profile_id} launched${proxy ? ' (proxy)' : ''}`);
|
|
236
|
+
|
|
237
|
+
await this.api.updateCommand(command._id, {
|
|
238
|
+
status: 'done',
|
|
239
|
+
result: { profile_id: result.profileId, launched_at: new Date().toISOString() },
|
|
240
|
+
});
|
|
241
|
+
} catch (err) {
|
|
242
|
+
console.error(`[commands] Failed to launch Veo3 profile: ${err.message}`);
|
|
243
|
+
await this.api.updateCommand(command._id, {
|
|
244
|
+
status: 'failed',
|
|
245
|
+
error: err.message,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
170
250
|
async handleScanFacebookPages(command) {
|
|
171
251
|
const { profile_id } = command.payload || {};
|
|
172
252
|
console.log(`[commands] Scan Facebook pages — launching profile: ${profile_id}`);
|
package/lib/nst-manager.js
CHANGED
|
@@ -65,19 +65,20 @@ class NstManager {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
// Create profile if not exists, return profileId
|
|
68
|
-
async ensureProfile(name) {
|
|
68
|
+
async ensureProfile(name, options = {}) {
|
|
69
69
|
const existing = await this.findProfile(name);
|
|
70
70
|
if (existing) {
|
|
71
71
|
console.log(`[nst] Profile "${name}" exists: ${existing}`);
|
|
72
72
|
return existing;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
const platform = (options.os || 'windows').toLowerCase() === 'mac' ? 'MacOS' : 'Windows';
|
|
76
|
+
console.log(`[nst] WARNING: Profile "${name}" NOT FOUND — creating new profile (${platform})...`);
|
|
76
77
|
const res = await this.api('/profiles', {
|
|
77
78
|
method: 'POST',
|
|
78
79
|
body: JSON.stringify({
|
|
79
80
|
name,
|
|
80
|
-
platform
|
|
81
|
+
platform,
|
|
81
82
|
kernelMilestone: '132',
|
|
82
83
|
fingerprint: {
|
|
83
84
|
flags: {
|