channel-worker 2.5.67 → 2.5.69
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 +1 -1
- package/scripts/upload_facebook.js +47 -16
package/package.json
CHANGED
|
@@ -29,6 +29,31 @@ const REEL_CREATE_SELECTORS = [
|
|
|
29
29
|
"a[aria-label='Create a reel']",
|
|
30
30
|
"a[href*='/reels/create']",
|
|
31
31
|
];
|
|
32
|
+
// Nút mở hộp chọn file BÊN TRONG hộp thoại "Tạo thước phim". Facebook phục vụ
|
|
33
|
+
// ÍT NHẤT hai biến thể, đổi theo phiên (cùng họ với A/B trình sửa ảnh bìa):
|
|
34
|
+
// 1. Nút riêng có aria-label "Tải lên"/"Upload" — không có chữ hiển thị.
|
|
35
|
+
// 2. Vùng thả file mang chữ "Tải video lên / hoặc kéo và thả" (aria rỗng).
|
|
36
|
+
// Sự cố 01/09 (idea 6a94fd58…, kênh Đồ chơi trẻ em 01, 4 lượt liên tiếp): chỉ
|
|
37
|
+
// biến thể 2 xuất hiện, mà danh sách cũ dò 'Tải lên' — chuỗi này KHÔNG nằm liền
|
|
38
|
+
// trong "Tải video lên" (có chữ "video" chen giữa) nên trượt hết, dù ảnh chụp
|
|
39
|
+
// lúc lỗi cho thấy nút nằm ngay đó. Thứ tự: nút chính xác trước, vùng thả sau.
|
|
40
|
+
const ADD_VIDEO_SELECTORS = [
|
|
41
|
+
"div[role='button']:has-text('Tải lên')",
|
|
42
|
+
"button:has-text('Tải lên')",
|
|
43
|
+
"[aria-label='Tải lên']",
|
|
44
|
+
"div[role='button']:has-text('Upload')",
|
|
45
|
+
"[aria-label='Upload']",
|
|
46
|
+
"div[role='button']:has-text('Thêm video')",
|
|
47
|
+
"div[role='button']:has-text('Add video')",
|
|
48
|
+
"[aria-label='Thêm video']",
|
|
49
|
+
"[aria-label='Add video']",
|
|
50
|
+
// Biến thể vùng thả (01/09).
|
|
51
|
+
"div[role='button']:has-text('Tải video lên')",
|
|
52
|
+
"div[role='button']:has-text('Upload video')",
|
|
53
|
+
"[aria-label='Tải video lên']",
|
|
54
|
+
"[aria-label='Upload video']",
|
|
55
|
+
];
|
|
56
|
+
|
|
32
57
|
const REEL_ENTRY_SELECTORS = [
|
|
33
58
|
"div[role='region'][aria-label='Tạo bài viết'] [aria-label='Thước phim']",
|
|
34
59
|
"div[role='region'][aria-label='Tạo bài viết'] [aria-label='Reel']",
|
|
@@ -409,7 +434,7 @@ async function cdpSetInputFiles(page, inputHandle, filePath, log, tag) {
|
|
|
409
434
|
});
|
|
410
435
|
if (!nodeId) throw new Error('CDP querySelector: tagged input not found');
|
|
411
436
|
await cdp.send('DOM.setFileInputFiles', { files: [filePath], nodeId });
|
|
412
|
-
log('info', `[${tag}] file set via CDP DOM.setFileInputFiles (
|
|
437
|
+
log('info', `[${tag}] file set via CDP DOM.setFileInputFiles (đường truyền path, mọi dung lượng)`);
|
|
413
438
|
} finally {
|
|
414
439
|
await inputHandle.evaluate((el, a) => el.removeAttribute(a), ATTR).catch(() => {});
|
|
415
440
|
if (cdp) await cdp.detach().catch(() => {});
|
|
@@ -421,12 +446,24 @@ async function cdpSetInputFiles(page, inputHandle, filePath, log, tag) {
|
|
|
421
446
|
// falls back to the CDP command only on the size error.
|
|
422
447
|
async function setVideoFile(page, inputHandle, filePath, log, tag = 'fb-pw') {
|
|
423
448
|
if (!inputHandle) throw new Error('setVideoFile: no input handle');
|
|
449
|
+
// VÙNG CHẾT 20-50MB (đo thật 01/09): native setInputFiles đẩy TOÀN BỘ byte
|
|
450
|
+
// qua CDP dưới dạng base64, nên file vừa đủ lớn là quá 30s mặc định của
|
|
451
|
+
// Playwright và ném TimeoutError — trong khi >50MB lại ném đúng chữ "larger
|
|
452
|
+
// than 50MB" nên được rơi về CDP và chạy ngon. Kết quả: video 44,1MB fail,
|
|
453
|
+
// còn 163MB cùng kênh đăng bình thường.
|
|
454
|
+
//
|
|
455
|
+
// DOM.setFileInputFiles truyền ĐƯỜNG DẪN chứ không đẩy byte, nên hợp mọi
|
|
456
|
+
// dung lượng. Vì vậy: native chỉ được thử nhanh (12s) như đường tắt, hỏng vì
|
|
457
|
+
// BẤT KỲ lý do gì cũng rơi về CDP — không lọc theo thông điệp lỗi nữa, chính
|
|
458
|
+
// cái lọc đó là thứ giấu mất đường cứu.
|
|
459
|
+
// Vì browser nối qua CDP nên Playwright coi nó là "remote" và đẩy file dưới
|
|
460
|
+
// dạng base64 — 44MB thành ~59MB trên dây, quá 30s mặc định. Cho hẳn 150s:
|
|
461
|
+
// native là đường ĐÃ CHẠY ĐƯỢC 829 lượt, chỉ thiếu giờ chứ không hỏng.
|
|
424
462
|
try {
|
|
425
|
-
await inputHandle.setInputFiles(filePath
|
|
463
|
+
await inputHandle.setInputFiles(filePath, { timeout: 150000 });
|
|
426
464
|
return;
|
|
427
465
|
} catch (e) {
|
|
428
|
-
|
|
429
|
-
log('info', `[${tag}] native setInputFiles hit the 50MB CDP cap — switching to DOM.setFileInputFiles…`);
|
|
466
|
+
log('info', `[${tag}] native setInputFiles không xong (${String(e.message || '').slice(0, 70)}) — chuyển sang DOM.setFileInputFiles…`);
|
|
430
467
|
}
|
|
431
468
|
await cdpSetInputFiles(page, inputHandle, filePath, log, tag);
|
|
432
469
|
}
|
|
@@ -771,7 +808,9 @@ async function runOnce({ page, payload, log }) {
|
|
|
771
808
|
if (await reelsDialog.isVisible({ timeout }).catch(() => false)) return reelsDialog;
|
|
772
809
|
if (/\/reels\/create\/?/i.test(page.url())
|
|
773
810
|
&& await fullPageComposer.isVisible({ timeout: 1000 }).catch(() => false)) {
|
|
774
|
-
|
|
811
|
+
// Cùng điểm mù với ADD_VIDEO_SELECTORS: biến thể vùng thả không mang
|
|
812
|
+
// aria-label nào, chỉ có chữ hiển thị.
|
|
813
|
+
const hasUploadUi = await fullPageComposer.locator("input[type='file'], [aria-label='Tải lên'], [aria-label='Upload'], [aria-label='Thêm video'], [aria-label='Add video'], div[role='button']:has-text('Tải video lên'), div[role='button']:has-text('Upload video')")
|
|
775
814
|
.count().catch(() => 0);
|
|
776
815
|
if (hasUploadUi) return fullPageComposer;
|
|
777
816
|
}
|
|
@@ -821,17 +860,7 @@ async function runOnce({ page, payload, log }) {
|
|
|
821
860
|
// - "Tải lên" — the explicit blue upload button at the bottom (preferred)
|
|
822
861
|
// - "Thêm video" — the drop-zone label (clickable on some variants)
|
|
823
862
|
// - English equivalents
|
|
824
|
-
const addVideoCandidates =
|
|
825
|
-
reelsRoot.locator("div[role='button']:has-text('Tải lên')"),
|
|
826
|
-
reelsRoot.locator("button:has-text('Tải lên')"),
|
|
827
|
-
reelsRoot.locator("[aria-label='Tải lên']"),
|
|
828
|
-
reelsRoot.locator("div[role='button']:has-text('Upload')"),
|
|
829
|
-
reelsRoot.locator("[aria-label='Upload']"),
|
|
830
|
-
reelsRoot.locator("div[role='button']:has-text('Thêm video')"),
|
|
831
|
-
reelsRoot.locator("div[role='button']:has-text('Add video')"),
|
|
832
|
-
reelsRoot.locator("[aria-label='Thêm video']"),
|
|
833
|
-
reelsRoot.locator("[aria-label='Add video']"),
|
|
834
|
-
];
|
|
863
|
+
const addVideoCandidates = ADD_VIDEO_SELECTORS.map(sel => reelsRoot.locator(sel));
|
|
835
864
|
let videoSet = false;
|
|
836
865
|
for (const loc of addVideoCandidates) {
|
|
837
866
|
if (videoSet) break;
|
|
@@ -2779,5 +2808,7 @@ module.exports.__testables = {
|
|
|
2779
2808
|
PUBLISH_ENABLE_TIMEOUT_MS,
|
|
2780
2809
|
REEL_CREATE_SELECTORS,
|
|
2781
2810
|
REEL_ENTRY_SELECTORS,
|
|
2811
|
+
ADD_VIDEO_SELECTORS,
|
|
2812
|
+
setVideoFile,
|
|
2782
2813
|
FB_REEL_CREATE_URL,
|
|
2783
2814
|
};
|