channel-worker 2.5.126 → 2.5.127
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/comment_facebook.js +35 -60
package/package.json
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
|
-
// Thả link affiliate xuống BÌNH LUẬN của một bài Facebook đã đăng
|
|
1
|
+
// Thả link affiliate xuống BÌNH LUẬN của một bài Facebook đã đăng.
|
|
2
2
|
//
|
|
3
3
|
// Vì sao là bình luận chứ không phải caption: bài đang lên view thì không ai đi
|
|
4
4
|
// sửa caption của nó — sửa caption là bài quay lại hàng đợi xét duyệt của
|
|
5
|
-
// Facebook giữa lúc nó đang được phân phối. Bình luận thì
|
|
6
|
-
//
|
|
5
|
+
// Facebook giữa lúc nó đang được phân phối. Bình luận thì sửa được, xoá được,
|
|
6
|
+
// không đụng vào bài.
|
|
7
7
|
//
|
|
8
8
|
// Chạy trên chính profile NST của kênh (máy đăng bài) chứ không phải máy
|
|
9
|
-
// Shopee: bình luận phải mang danh Page
|
|
10
|
-
// bài của mình do tài khoản khác thả thì
|
|
9
|
+
// Shopee: bình luận phải mang danh Page — Facebook mới gắn nhãn "Author" và ưu
|
|
10
|
+
// tiên hiển thị nó, còn một link lạ dưới bài của mình do tài khoản khác thả thì
|
|
11
|
+
// người xem đọc ra là spam.
|
|
11
12
|
//
|
|
12
|
-
// Payload: { post_url, text, link,
|
|
13
|
+
// Payload: { post_url, text, link, idea_id?, channel_id? }
|
|
13
14
|
// post_url: link bài đã XÁC MINH (API chặn sẵn ô rỗng — services/AffComment)
|
|
14
15
|
// text: nguyên câu bình luận sẽ gõ, đã gồm link
|
|
15
16
|
// link: riêng chuỗi link, dùng để ĐỌC LẠI xác minh — xem `verified`
|
|
16
17
|
//
|
|
17
|
-
// Trả về { verified, comment_url, commented_as,
|
|
18
|
+
// Trả về { verified, comment_url, commented_as, post_url }.
|
|
19
|
+
//
|
|
20
|
+
// KHÔNG có bước ghim. Facebook không cho ghim bình luận dưới reel ở giao diện
|
|
21
|
+
// web — chủ tịch mở tận nơi kiểm 21/09, menu ⋯ của bình luận không có mục đó,
|
|
22
|
+
// kể cả khi bình luận đã mang nhãn "Author" (tức của chính chủ bài). Bản cũ
|
|
23
|
+
// vẫn đi dò nút ấy mỗi lượt rồi ghi một dòng log nghe như mình làm hỏng việc.
|
|
24
|
+
// Bỏ luôn: bình luận của tác giả bài vốn được Facebook ưu tiên hiển thị.
|
|
18
25
|
//
|
|
19
26
|
// ⚠️ LUẬT LÕI CỦA SCRIPT NÀY: `verified` chỉ được true khi đã đọc lại thấy một
|
|
20
27
|
// bình luận THẬT trên trang mang đúng chuỗi link. Gõ xong + bấm Enter KHÔNG
|
|
@@ -191,16 +198,28 @@ async function findPostedComment(page, link) {
|
|
|
191
198
|
if (node.querySelector("[contenteditable='true']") && !node.getAttribute('aria-label')) continue;
|
|
192
199
|
const label = node.getAttribute('aria-label') || '';
|
|
193
200
|
const m = /(?:Bình luận của|Comment by)\s+(.+)$/i.exec(label.trim());
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
201
|
+
// Khối bình luận KHÔNG phải lúc nào cũng mang aria-label "Bình luận của
|
|
202
|
+
// <Tên>" — giao diện reel không dùng nhãn đó, nên mọi lượt thả reel đều
|
|
203
|
+
// về `commented_as` rỗng và `comment_url` rỗng (21/09). Bằng chứng chắc
|
|
204
|
+
// chắn khác, không phụ thuộc chữ nghĩa giao diện: khối có link permalink
|
|
205
|
+
// mang `comment_id=`. Khối BÀI không bao giờ có thứ đó, nên vẫn né được
|
|
206
|
+
// đúng cái bẫy mà nhãn kia sinh ra để né — caption bài chứa chuỗi link.
|
|
199
207
|
const a = node.querySelector("a[href*='comment_id=']");
|
|
208
|
+
if (!m && !a) continue;
|
|
209
|
+
out.found = true;
|
|
200
210
|
if (a) {
|
|
201
211
|
const href = a.getAttribute('href') || '';
|
|
202
212
|
out.comment_url = href.startsWith('http') ? href : `https://www.facebook.com${href}`;
|
|
203
213
|
}
|
|
214
|
+
if (m) {
|
|
215
|
+
out.author = m[1].trim().slice(0, 120);
|
|
216
|
+
} else {
|
|
217
|
+
// Facebook gắn nhãn "Author"/"Tác giả" cho bình luận của chính chủ bài
|
|
218
|
+
// — với luồng này thì đó CHÍNH LÀ điều cần biết: bình luận mang danh
|
|
219
|
+
// Page chứ không phải một tài khoản lạ đi rải link dưới bài của kênh.
|
|
220
|
+
const badge = /(^|\s)(Author|Tác giả)(\s|$)/i.test(node.innerText || '');
|
|
221
|
+
out.author = badge ? 'Author' : '';
|
|
222
|
+
}
|
|
204
223
|
return out;
|
|
205
224
|
}
|
|
206
225
|
return out;
|
|
@@ -225,46 +244,6 @@ async function waitForPostedComment(page, link, log, timeoutMs = VERIFY_TIMEOUT_
|
|
|
225
244
|
return { ...meta, found: false, count: n };
|
|
226
245
|
}
|
|
227
246
|
|
|
228
|
-
// ─── ghim ───────────────────────────────────────────────────────────────────
|
|
229
|
-
|
|
230
|
-
// Ghim là việc CÓ CŨNG TỐT, không có cũng xong: link đã nằm dưới bài rồi. Nên
|
|
231
|
-
// mọi lỗi ở đây chỉ ghi log và trả false, KHÔNG ném — hỏng bước ghim mà đánh
|
|
232
|
-
// cả lệnh thành thất bại thì lượt chạy lại sẽ thả bình luận thứ hai.
|
|
233
|
-
async function pinComment(page, link, log) {
|
|
234
|
-
try {
|
|
235
|
-
const menuBtn = await page.evaluateHandle((needle) => {
|
|
236
|
-
const nodes = [...document.querySelectorAll("[role='article']")];
|
|
237
|
-
for (const node of nodes) {
|
|
238
|
-
if (!(node.innerText || '').includes(needle)) continue;
|
|
239
|
-
if (!/(Bình luận của|Comment by)/i.test(node.getAttribute('aria-label') || '')) continue;
|
|
240
|
-
const btn = [...node.querySelectorAll("[role='button'], [aria-haspopup='menu']")]
|
|
241
|
-
.find((b) => /hành động|tùy chọn|tuỳ chọn|options|actions/i.test(b.getAttribute('aria-label') || ''));
|
|
242
|
-
if (btn) { btn.scrollIntoView({ block: 'center' }); return btn; }
|
|
243
|
-
}
|
|
244
|
-
return null;
|
|
245
|
-
}, link);
|
|
246
|
-
const el = menuBtn.asElement();
|
|
247
|
-
if (!el) { log('info', '[fb-cmt] không thấy nút ⋯ của bình luận — bỏ qua bước ghim'); return false; }
|
|
248
|
-
await el.click({ timeout: 5000 }).catch(() => {});
|
|
249
|
-
await pause(page, 1200);
|
|
250
|
-
|
|
251
|
-
const item = page.locator("[role='menuitem'], [role='menu'] [role='button']")
|
|
252
|
-
.filter({ hasText: /Ghim bình luận|Ghim|Pin comment|Pin/i }).first();
|
|
253
|
-
if (!(await item.isVisible().catch(() => false))) {
|
|
254
|
-
log('info', '[fb-cmt] menu không có mục Ghim (thường là chưa bình luận bằng danh Page) — bỏ qua');
|
|
255
|
-
await page.keyboard.press('Escape').catch(() => {});
|
|
256
|
-
return false;
|
|
257
|
-
}
|
|
258
|
-
await item.click({ timeout: 5000 }).catch(() => {});
|
|
259
|
-
await pause(page, 1500);
|
|
260
|
-
log('info', '[fb-cmt] đã bấm Ghim bình luận');
|
|
261
|
-
return true;
|
|
262
|
-
} catch (e) {
|
|
263
|
-
log('warn', `[fb-cmt] ghim hỏng (bỏ qua, link vẫn nằm dưới bài): ${e.message.slice(0, 120)}`);
|
|
264
|
-
return false;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
247
|
// ─── thân ───────────────────────────────────────────────────────────────────
|
|
269
248
|
|
|
270
249
|
async function run({ page, payload = {}, log }) {
|
|
@@ -357,23 +336,19 @@ async function run({ page, payload = {}, log }) {
|
|
|
357
336
|
// 'failed' kèm nguyên văn. Ném lỗi ở đây thì lượt chạy lại sẽ gõ thêm một
|
|
358
337
|
// bình luận nữa, mà bình luận trước có thể đã nằm đó rồi.
|
|
359
338
|
log('warn', '[fb-cmt] gõ và gửi xong nhưng KHÔNG đọc lại thấy bình luận — coi như chưa thả, người phải vào kiểm');
|
|
360
|
-
return { verified: false, post_url: postUrl, comment_url: '', commented_as: ''
|
|
339
|
+
return { verified: false, post_url: postUrl, comment_url: '', commented_as: '' };
|
|
361
340
|
}
|
|
362
341
|
|
|
363
342
|
log('info', `[fb-cmt] xác minh được bình luận — danh nghĩa "${found.author}"${found.comment_url ? ` · ${found.comment_url}` : ''}`);
|
|
364
343
|
|
|
365
|
-
let pinned = false;
|
|
366
|
-
if (payload.pin !== false) pinned = await pinComment(page, link, log);
|
|
367
|
-
|
|
368
344
|
return {
|
|
369
345
|
verified: true,
|
|
370
346
|
post_url: postUrl,
|
|
371
347
|
comment_url: found.comment_url || '',
|
|
372
|
-
// Tên hiện trên bình luận
|
|
373
|
-
//
|
|
374
|
-
// người xem đọc ra là spam của
|
|
348
|
+
// Tên hiện trên bình luận, hoặc 'Author' khi Facebook gắn nhãn tác giả.
|
|
349
|
+
// Ra tên người lạ nghĩa là profile đang bình luận bằng tài khoản cá nhân —
|
|
350
|
+
// người xem đọc ra là spam dưới bài của kênh.
|
|
375
351
|
commented_as: found.author || '',
|
|
376
|
-
pinned,
|
|
377
352
|
};
|
|
378
353
|
}
|
|
379
354
|
|