channel-worker 2.5.79 → 2.5.80

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.79",
3
+ "version": "2.5.80",
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": {
@@ -157,10 +157,41 @@ function parseVnPostTime(txt, now = new Date()) {
157
157
  return Number.isNaN(t.getTime()) ? null : t.toISOString();
158
158
  }
159
159
 
160
+ // Nhãn khoảng thời gian PHẢI khớp cái đã xin. Trang dựng khung trước rồi mới
161
+ // đổ số, nên đọc quá sớm là lấy trúng số của khoảng TRƯỚC ĐÓ mà không có dấu
162
+ // hiệu gì. Đo thật 2026-09-06: 5/43 lượt xin LAST_7D nhận về "Hôm nay", và một
163
+ // kênh ghi được daily_views 279.946 trong khi views_7d chỉ 278.662 — tức là số
164
+ // 28 ngày bị nhét vào ô "hôm nay". Phải ĐỢI nhãn khớp, không thì thà hỏng to.
165
+ const RANGE_LABEL = {
166
+ TODAY: /hôm nay/i,
167
+ LAST_7D: /7 ngày qua/i,
168
+ LAST_14D: /14 ngày qua/i,
169
+ LAST_28D: /28 ngày qua/i,
170
+ LAST_60D: /60 ngày qua/i,
171
+ LAST_90D: /90 ngày qua/i,
172
+ };
173
+
160
174
  async function readViewsPage(page, range, log) {
161
175
  const url = `${INSIGHTS_BASE}/views/?tab=reels&date_range=${range}`;
162
176
  await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 45_000 });
163
- await page.waitForTimeout(7000);
177
+ const want = RANGE_LABEL[range];
178
+ let label = '';
179
+ // Tối đa ~24s: khung trang hiện trong ~3s, số đổ về chậm hơn nhiều.
180
+ for (let i = 0; i < 12; i++) {
181
+ await page.waitForTimeout(2000);
182
+ label = await page.evaluate(() => {
183
+ const clean = (v) => String(v || '').replace(/\s+/g, ' ').trim();
184
+ for (const e of document.querySelectorAll('div,span')) {
185
+ const t = clean(e.innerText);
186
+ if (t.length < 60 && /Tổng số lượt xem/i.test(t)) return t;
187
+ }
188
+ return '';
189
+ }).catch(() => '');
190
+ if (label && (!want || want.test(label))) break;
191
+ }
192
+ if (want && !want.test(label)) {
193
+ throw new Error(`xin ${range} nhưng sau 24s trang vẫn hiện "${label || 'chưa có số nào'}"`);
194
+ }
164
195
  const raw = await page.evaluate(() => {
165
196
  const clean = (v) => String(v || '').replace(/\s+/g, ' ').trim();
166
197
  const seen = new Set(); const chunks = [];
@@ -191,8 +222,8 @@ async function readViewsPage(page, range, log) {
191
222
  const views = parseExact(m[2]);
192
223
  if (at && views != null && !posts.some((p) => p.at === at)) posts.push({ at, views, raw: m[0].slice(0, 60) });
193
224
  }
194
- log('info', `[insights] ${range}: tổng ${total}${pct != null ? ` (${pct}%)` : ''}, ${posts.length} bài — nhãn "${raw.label}"`);
195
- return { range, label: raw.label, total, pct, posts };
225
+ log('info', `[insights] ${range}: tổng ${total}${pct != null ? ` (${pct}%)` : ''}, ${posts.length} bài — "${label}"`);
226
+ return { range, label, total, pct, posts };
196
227
  }
197
228
 
198
229
  async function readAudiencePage(page, log) {
@@ -229,10 +260,6 @@ async function runInsights({ page, payload, log }) {
229
260
  if (today.total == null && week.total == null) {
230
261
  throw new Error('không đọc được tổng lượt xem trên trang Insights — FB đổi giao diện?');
231
262
  }
232
- // Nhãn phải khớp khoảng đã xin: token sai thì trang im lặng rơi về 28 ngày.
233
- if (week.label && !/7 ngày qua/i.test(week.label)) {
234
- throw new Error(`xin LAST_7D nhưng trang trả về "${week.label}" — token date_range đã đổi`);
235
- }
236
263
  if (typeof log.apiRequest !== 'function') throw new Error('log.apiRequest không có — cần channel-worker ≥ 2.5.55');
237
264
  const d = await log.apiRequest('POST', '/analytics/fb-insights', {
238
265
  channel_id: payload.channel_id,