channel-worker 2.5.48 → 2.5.50

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "channel-worker",
3
- "version": "2.5.48",
3
+ "version": "2.5.50",
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": {
@@ -170,11 +170,25 @@ async function scanFeed(page, { skipKeys = [], wantLike = false } = {}) {
170
170
  break;
171
171
  }
172
172
  }
173
+ // Which element is actually scrolling? Facebook has shipped both a
174
+ // window-scrolled feed and one inside its own overflow container; if we
175
+ // measure the wrong one, "the page didn't move" is a false alarm.
176
+ let scroller = 'window', scrollTop = Math.round(window.scrollY || 0);
177
+ if (!scrollTop) {
178
+ for (const el of document.querySelectorAll('div')) {
179
+ if (el.scrollTop > 50 && el.scrollHeight > el.clientHeight + 200) {
180
+ scroller = 'div.' + String(el.className || '').split(' ')[0];
181
+ scrollTop = Math.round(el.scrollTop);
182
+ break;
183
+ }
184
+ }
185
+ }
173
186
  return {
174
- posts, likeKey,
187
+ posts, likeKey, scroller, scrollTop,
175
188
  scrollY: Math.round(window.scrollY || document.documentElement.scrollTop || 0),
176
189
  articlesInDom: units.length,
177
190
  selector: sel || '(none)',
191
+ sample: posts.slice(0, 3).map((p) => p.key.slice(0, 46)),
178
192
  };
179
193
  }, { skip: skipKeys, wantLike }).catch(() => ({ posts: [], likeKey: null, scrollY: 0, articlesInDom: 0 }));
180
194
  }
@@ -337,6 +351,26 @@ async function followVisiblePage(page, log) {
337
351
  return ok;
338
352
  }
339
353
 
354
+ // debug:true only — screenshot the feed and hand back a viewable URL. Cheaper
355
+ // than another round of guessing at selectors from log lines.
356
+ async function dumpFeedShot(page, log, tag) {
357
+ try {
358
+ const fs = require('fs');
359
+ const os = require('os');
360
+ const path = require('path');
361
+ const dir = path.join(os.tmpdir(), 'cm-worker-pw');
362
+ fs.mkdirSync(dir, { recursive: true });
363
+ const png = path.join(dir, `nurture-${tag}-${Date.now()}.png`);
364
+ await page.screenshot({ path: png, fullPage: false, timeout: 8000 }).catch(() => {});
365
+ if (fs.existsSync(png) && typeof log.uploadDebugScreenshot === 'function') {
366
+ const url = await log.uploadDebugScreenshot(png, { tag });
367
+ log('warn', `[nurture-fb][dbg] screenshot ${tag}: ${url && url.url ? url.url : JSON.stringify(url)}`);
368
+ }
369
+ } catch (e) {
370
+ log('info', `[nurture-fb][dbg] screenshot failed: ${String(e.message || e).slice(0, 80)}`);
371
+ }
372
+ }
373
+
340
374
  // ─── main ───────────────────────────────────────────────────────────────────
341
375
  async function run({ page, payload, log }) {
342
376
  const t0 = Date.now();
@@ -364,6 +398,7 @@ async function run({ page, payload, log }) {
364
398
  await dismissDialogs(page, log);
365
399
 
366
400
  await centerMouse(page); // wheel events need the cursor over the feed column
401
+ if (payload.debug) await dumpFeedShot(page, log, 'feed-start');
367
402
 
368
403
  let postsSeen = 0, likes = 0, videos = 0, pagesFollowed = 0, postsOpened = 0;
369
404
  let postsSinceLike = likeGap; // allow the first like once enough posts scroll by
@@ -385,6 +420,11 @@ async function run({ page, payload, log }) {
385
420
  seenKeys.add(p.key);
386
421
  if (!p.isAd) fresh++; // scrolling past an ad isn't reading
387
422
  }
423
+ // debug:true (probe runs only) — dumps what the scan actually saw so a
424
+ // wrong selector / duplicate key shows up as data instead of a guess.
425
+ if (payload.debug && ticks % 3 === 0) {
426
+ log('info', `[nurture-fb][dbg] t${ticks} scroller=${scan.scroller}@${scan.scrollTop} winY=${scan.scrollY} sel=${scan.selector} units=${scan.articlesInDom} fresh=${fresh} keys=${JSON.stringify(scan.sample)}`);
427
+ }
388
428
  postsSeen += fresh;
389
429
  postsSinceLike += fresh;
390
430
  // Feed that stops yielding posts for ~15 ticks = end of feed, a wall, or a