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
|
@@ -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
|
-
|
|
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 —
|
|
195
|
-
return { range, label
|
|
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,
|