channel-worker 2.5.79 → 2.5.81

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.81",
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,51 @@ 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
+ // Hai ca KHÁC HẲN nhau, đừng gộp:
193
+ // nhãn RỖNG = khoảng này chưa có số nào. Chuyện thường, không phải lỗi —
194
+ // lúc 0h sáng thì "Hôm nay" đương nhiên trống. Trả null, và
195
+ // vẫn đọc tiếp hai trang còn lại.
196
+ // nhãn KHÁC = trang đang hiện số của khoảng KHÁC. Đây mới là nguy hiểm:
197
+ // đọc tiếp là ghi số 28 ngày vào ô "hôm nay". Hỏng to.
198
+ if (label && want && !want.test(label)) {
199
+ throw new Error(`xin ${range} nhưng sau 24s trang vẫn hiện "${label}"`);
200
+ }
201
+ if (!label) {
202
+ log('info', `[insights] ${range}: trang chưa có số nào (khoảng này trống)`);
203
+ return { range, label: '', total: null, pct: null, posts: [] };
204
+ }
164
205
  const raw = await page.evaluate(() => {
165
206
  const clean = (v) => String(v || '').replace(/\s+/g, ' ').trim();
166
207
  const seen = new Set(); const chunks = [];
@@ -191,8 +232,8 @@ async function readViewsPage(page, range, log) {
191
232
  const views = parseExact(m[2]);
192
233
  if (at && views != null && !posts.some((p) => p.at === at)) posts.push({ at, views, raw: m[0].slice(0, 60) });
193
234
  }
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 };
235
+ log('info', `[insights] ${range}: tổng ${total}${pct != null ? ` (${pct}%)` : ''}, ${posts.length} bài — "${label}"`);
236
+ return { range, label, total, pct, posts };
196
237
  }
197
238
 
198
239
  async function readAudiencePage(page, log) {
@@ -229,10 +270,6 @@ async function runInsights({ page, payload, log }) {
229
270
  if (today.total == null && week.total == null) {
230
271
  throw new Error('không đọc được tổng lượt xem trên trang Insights — FB đổi giao diện?');
231
272
  }
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
273
  if (typeof log.apiRequest !== 'function') throw new Error('log.apiRequest không có — cần channel-worker ≥ 2.5.55');
237
274
  const d = await log.apiRequest('POST', '/analytics/fb-insights', {
238
275
  channel_id: payload.channel_id,