channel-worker 1.0.6 → 1.0.8
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/command-poller.js +19 -34
- package/lib/nst-manager.js +33 -0
- package/package.json +3 -2
package/lib/command-poller.js
CHANGED
|
@@ -46,15 +46,11 @@ class CommandPoller {
|
|
|
46
46
|
case 'close_profile':
|
|
47
47
|
await this.handleCloseProfile(command);
|
|
48
48
|
break;
|
|
49
|
-
case 'scan_facebook_pages':
|
|
50
|
-
await this.handleScanFacebookPages(command);
|
|
51
|
-
break;
|
|
52
|
-
case 'verify_logins':
|
|
53
|
-
await this.handleVerifyLogins(command);
|
|
54
|
-
break;
|
|
55
49
|
default:
|
|
56
|
-
|
|
57
|
-
|
|
50
|
+
// Other commands (scan_facebook_pages, etc.) handled by extension
|
|
51
|
+
console.log(`[commands] Skipping ${command.type} — handled by extension`);
|
|
52
|
+
// Reset to pending so extension can pick it up
|
|
53
|
+
await this.api.updateCommand(command._id, { status: 'pending' });
|
|
58
54
|
}
|
|
59
55
|
} catch (err) {
|
|
60
56
|
if (this.config.verbose) {
|
|
@@ -105,7 +101,7 @@ class CommandPoller {
|
|
|
105
101
|
|
|
106
102
|
async handleScanFacebookPages(command) {
|
|
107
103
|
const { profile_id } = command.payload || {};
|
|
108
|
-
console.log(`[commands]
|
|
104
|
+
console.log(`[commands] Scan Facebook pages — launching profile: ${profile_id}`);
|
|
109
105
|
|
|
110
106
|
try {
|
|
111
107
|
if (!this.nst) {
|
|
@@ -117,36 +113,25 @@ class CommandPoller {
|
|
|
117
113
|
}
|
|
118
114
|
}
|
|
119
115
|
|
|
120
|
-
// Launch profile
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
// const browser = await puppeteer.connect({ browserWSEndpoint: wsEndpoint });
|
|
132
|
-
// const page = await browser.newPage();
|
|
133
|
-
// await page.goto('https://www.facebook.com/pages/?category=your_pages');
|
|
134
|
-
// pages = await page.evaluate(() => { /* scrape page names/urls */ });
|
|
135
|
-
|
|
136
|
-
// Send results to API
|
|
137
|
-
if (pages.length > 0) {
|
|
138
|
-
await this.api.request('POST', '/facebook-pages/scan-result', {
|
|
139
|
-
pages,
|
|
140
|
-
scanned_from_profile: profile_id,
|
|
141
|
-
});
|
|
142
|
-
}
|
|
116
|
+
// Launch profile
|
|
117
|
+
const extensionPath = this.config.extension_path || '';
|
|
118
|
+
await this.nst.launchProfile(profile_id, { extensionPath });
|
|
119
|
+
|
|
120
|
+
// Create a NEW command for extension to pick up (separate from worker command)
|
|
121
|
+
await this.api.request('POST', '/workers/commands', {
|
|
122
|
+
worker_id: this.config.worker_id,
|
|
123
|
+
type: 'scan_facebook_pages',
|
|
124
|
+
payload: { profile_id, channel_id: command.payload?.channel_id },
|
|
125
|
+
status: 'pending',
|
|
126
|
+
});
|
|
143
127
|
|
|
128
|
+
// Mark worker command as done
|
|
144
129
|
await this.api.updateCommand(command._id, {
|
|
145
130
|
status: 'done',
|
|
146
|
-
result: { profile_id:
|
|
131
|
+
result: { profile_id, message: 'Profile launched, extension command created' },
|
|
147
132
|
});
|
|
148
133
|
|
|
149
|
-
console.log(`[commands]
|
|
134
|
+
console.log(`[commands] Profile launched — extension will execute scan`);
|
|
150
135
|
} catch (err) {
|
|
151
136
|
console.error(`[commands] Facebook scan failed: ${err.message}`);
|
|
152
137
|
await this.api.updateCommand(command._id, {
|
package/lib/nst-manager.js
CHANGED
|
@@ -128,6 +128,39 @@ class NstManager {
|
|
|
128
128
|
console.log(`[nst] Starting browser for profile: ${profileId}`);
|
|
129
129
|
const res = await this.client.browsers().startBrowser(profileId);
|
|
130
130
|
console.log(`[nst] Browser started`);
|
|
131
|
+
|
|
132
|
+
// Set nstProfileId in chrome.storage via CDP
|
|
133
|
+
try {
|
|
134
|
+
// Wait for browser to fully start
|
|
135
|
+
await new Promise(r => setTimeout(r, 3000));
|
|
136
|
+
|
|
137
|
+
const debugInfo = await this.client.browsers().getBrowserDebugger(profileId);
|
|
138
|
+
const wsUrl = debugInfo?.data?.webSocketDebuggerUrl;
|
|
139
|
+
if (wsUrl) {
|
|
140
|
+
const WebSocket = require('ws');
|
|
141
|
+
const ws = new WebSocket(wsUrl);
|
|
142
|
+
await new Promise((resolve, reject) => {
|
|
143
|
+
const timeout = setTimeout(() => { ws.close(); reject(new Error('CDP timeout')); }, 10000);
|
|
144
|
+
ws.on('open', () => {
|
|
145
|
+
// Navigate a new tab to set storage
|
|
146
|
+
ws.send(JSON.stringify({
|
|
147
|
+
id: 1,
|
|
148
|
+
method: 'Runtime.evaluate',
|
|
149
|
+
params: {
|
|
150
|
+
expression: `chrome.storage && chrome.storage.local ? chrome.storage.local.set({nstProfileId: "${profileIdOrName}"}) : null`,
|
|
151
|
+
awaitPromise: true,
|
|
152
|
+
},
|
|
153
|
+
}));
|
|
154
|
+
setTimeout(() => { clearTimeout(timeout); ws.close(); resolve(); }, 2000);
|
|
155
|
+
});
|
|
156
|
+
ws.on('error', (e) => { clearTimeout(timeout); reject(e); });
|
|
157
|
+
});
|
|
158
|
+
console.log(`[nst] Profile ID "${profileIdOrName}" set in extension storage`);
|
|
159
|
+
}
|
|
160
|
+
} catch (e) {
|
|
161
|
+
console.log(`[nst] Could not set profile ID in storage: ${e.message}`);
|
|
162
|
+
}
|
|
163
|
+
|
|
131
164
|
return { profileId, response: res };
|
|
132
165
|
}
|
|
133
166
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "channel-worker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
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,8 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"node-fetch": "^3.3.2",
|
|
19
|
-
"nstbrowser-sdk-node": "^0.1.1"
|
|
19
|
+
"nstbrowser-sdk-node": "^0.1.1",
|
|
20
|
+
"ws": "^8.18.0"
|
|
20
21
|
},
|
|
21
22
|
"engines": {
|
|
22
23
|
"node": ">=18"
|