Update like

This commit is contained in:
NAME
2026-05-12 15:32:21 +00:00
parent 1d7bddae27
commit d6220c828e
4 changed files with 134 additions and 63 deletions
+11 -11
View File
@@ -19,7 +19,7 @@ export class SqsPosterWorker {
} }
async start() { async start() {
console.log(`🚀 Worker started for ${await this.sqs.getQueueName()}`); this.logger.log(`🚀 Worker started for ${await this.sqs.getQueueName()}`);
await this.notifyService.sendMessageToTele(`🚀 Worker started for ${await this.sqs.getQueueName()}`) await this.notifyService.sendMessageToTele(`🚀 Worker started for ${await this.sqs.getQueueName()}`)
//check cookie //check cookie
@@ -31,11 +31,11 @@ export class SqsPosterWorker {
let ReceiptHandle = ''; let ReceiptHandle = '';
while (true) { while (true) {
try { try {
console.log('worker get message ...'); this.logger.log('worker get message ...');
const msg = await this.sqs.getMessage(); const msg = await this.sqs.getMessage();
if (!msg) { if (!msg) {
console.log('no message , sleeping...'); this.logger.log('no message , sleeping...');
await this.sleep(10000); //sleep 10s await this.sleep(10000); //sleep 10s
continue; continue;
} }
@@ -63,7 +63,7 @@ export class SqsPosterWorker {
} }
private async process(data: any) { private async process(data: any) {
console.log('📩 Got job:', data); this.logger.log('📩 Got job:', data);
const {type, content, xSubmitProvider, tweetUrl, publishTo, tweetId, telegramChatId} = data; const {type, content, xSubmitProvider, tweetUrl, publishTo, tweetId, telegramChatId} = data;
switch (type) { switch (type) {
case 'X_POSTER_TWEET': { case 'X_POSTER_TWEET': {
@@ -111,16 +111,16 @@ export class SqsPosterWorker {
strategy: string = XStrategy.API_ONLY, strategy: string = XStrategy.API_ONLY,
) { ) {
try { try {
console.log(`==> doPostTweet`, publishTo); this.logger.log(`==> doPostTweet`, publishTo);
let sendSuccess = false; let sendSuccess = false;
if (publishTo.includes(SUPPORT_SOCIAL_PROVIDERS.FB)) { if (publishTo.includes(SUPPORT_SOCIAL_PROVIDERS.FB)) {
console.log(`==> doPostTweet publish to fb`); this.logger.log(`==> doPostTweet publish to fb`);
await this.facebookApi.postToPage(text); await this.facebookApi.postToPage(text);
await this.notifyService.sendMessageToTele(`Post to FB success`); await this.notifyService.sendMessageToTele(`Post to FB success`);
sendSuccess = true; sendSuccess = true;
} }
if (publishTo.includes(SUPPORT_SOCIAL_PROVIDERS.X)) { if (publishTo.includes(SUPPORT_SOCIAL_PROVIDERS.X)) {
console.log(`==> doPostTweet publish to X`); this.logger.log(`==> doPostTweet publish to X`);
// @ts-ignore // @ts-ignore
const r = await this.xRouterService.postTweet({text, strategy}); const r = await this.xRouterService.postTweet({text, strategy});
@@ -150,7 +150,7 @@ export class SqsPosterWorker {
strategy: string = XStrategy.BROWSER_COOKIE strategy: string = XStrategy.BROWSER_COOKIE
) { ) {
try { try {
console.log('doReplyTweet'); this.logger.log('doReplyTweet');
// @ts-ignore // @ts-ignore
const r = await this.xRouterService.postReply({text, tweetUrl, tweetId, strategy}); const r = await this.xRouterService.postReply({text, tweetUrl, tweetId, strategy});
if (r.success) { if (r.success) {
@@ -163,8 +163,8 @@ export class SqsPosterWorker {
return r return r
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(e);
console.log("Mã lỗi:", e.code); // Ví dụ: 'ECONNABORTED' (timeout), 'ERR_NETWORK' (mất mạng) this.logger.log("Mã lỗi:", e.code); // Ví dụ: 'ECONNABORTED' (timeout), 'ERR_NETWORK' (mất mạng)
console.log("Thông báo:", e.message); this.logger.log("Thông báo:", e.message);
await this.notifyService.sendMessageToTele(`Worker==> doReplyTweet error:${e.code} - ${e.message}`) await this.notifyService.sendMessageToTele(`Worker==> doReplyTweet error:${e.code} - ${e.message}`)
@@ -178,7 +178,7 @@ export class SqsPosterWorker {
strategy: string = XStrategy.BROWSER_COOKIE strategy: string = XStrategy.BROWSER_COOKIE
) { ) {
try { try {
console.log('doQuoteTweet'); this.logger.log('doQuoteTweet');
// @ts-ignore // @ts-ignore
const r = await this.xRouterService.postQuote({text, tweetUrl, tweetId, strategy}); const r = await this.xRouterService.postQuote({text, tweetUrl, tweetId, strategy});
if (r.success) { if (r.success) {
+113 -48
View File
@@ -60,15 +60,15 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
account: BrowserAccount, account: BrowserAccount,
useCache = true useCache = true
): Promise<BrowserContext> { ): Promise<BrowserContext> {
console.log('getOrCreateContext:1') this.logger.debug('getOrCreateContext:1')
// console.log({account}); // this.logger.debug({account});
const cached = this.contextPool.get(account.accountId); const cached = this.contextPool.get(account.accountId);
if (useCache && cached) { if (useCache && cached) {
console.log('getOrCreateContext:cached'); this.logger.debug('getOrCreateContext:cached');
cached.lastUsed = Date.now(); cached.lastUsed = Date.now();
return cached.ctx; return cached.ctx;
} }
console.log('getOrCreateContext:2') this.logger.debug('getOrCreateContext:2')
// LRU eviction // LRU eviction
if (this.contextPool.size >= this.MAX_CONTEXTS) { if (this.contextPool.size >= this.MAX_CONTEXTS) {
@@ -78,10 +78,10 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
await oldest[1].ctx.close().catch(() => null); await oldest[1].ctx.close().catch(() => null);
this.contextPool.delete(oldest[0]); this.contextPool.delete(oldest[0]);
} }
console.log('getOrCreateContext:3') this.logger.debug('getOrCreateContext:3')
const browser = await this.ensureBrowser(account.headless); const browser = await this.ensureBrowser(account.headless);
console.log('getOrCreateContext:4') this.logger.debug('getOrCreateContext:4')
const ctx = await browser.newContext({ const ctx = await browser.newContext({
userAgent: userAgent:
@@ -92,15 +92,15 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
locale: process.env.BROWSER_LOCALE || 'en-US', locale: process.env.BROWSER_LOCALE || 'en-US',
proxy: account.proxy ? {server: account.proxy} : undefined, proxy: account.proxy ? {server: account.proxy} : undefined,
}); });
console.log('getOrCreateContext:5') this.logger.debug('getOrCreateContext:5')
// Anti-detection: ẩn webdriver flag // Anti-detection: ẩn webdriver flag
await ctx.addInitScript(() => { await ctx.addInitScript(() => {
Object.defineProperty(navigator, 'webdriver', {get: () => undefined}); Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
}); });
console.log('getOrCreateContext:6') this.logger.debug('getOrCreateContext:6')
// console.log(account.cookies); // this.logger.debug(account.cookies);
await ctx.addCookies( await ctx.addCookies(
account.cookies.map((c) => ({ account.cookies.map((c) => ({
@@ -111,9 +111,9 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
); );
this.contextPool.set(account.accountId, {ctx, lastUsed: Date.now()}); this.contextPool.set(account.accountId, {ctx, lastUsed: Date.now()});
console.log('getOrCreateContext:7') this.logger.debug('getOrCreateContext:7')
// console.log({ // this.logger.debug({
// ctx // ctx
// }) // })
return ctx; return ctx;
@@ -126,9 +126,9 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
async getPage(account: BrowserAccount): Promise<Page> { async getPage(account: BrowserAccount): Promise<Page> {
let ctx = await this.getOrCreateContext(account); let ctx = await this.getOrCreateContext(account);
console.log('Đã khởi tạo ctx') this.logger.debug('Đã khởi tạo ctx')
if (ctx.isClosed()) { if (ctx.isClosed()) {
console.log('browser is closeed, reopen'); this.logger.debug('browser is closeed, reopen');
ctx = await this.getOrCreateContext(account, false); ctx = await this.getOrCreateContext(account, false);
} }
const cookies = account.cookies.map((c) => ({ const cookies = account.cookies.map((c) => ({
@@ -136,7 +136,7 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
domain: c.domain || '.x.com', domain: c.domain || '.x.com',
path: c.path || '/', path: c.path || '/',
})); }));
// console.log('cookies:', cookies); // this.logger.debug('cookies:', cookies);
await ctx.addCookies(cookies); await ctx.addCookies(cookies);
return ctx.newPage(); return ctx.newPage();
} }
@@ -178,6 +178,68 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
} }
} }
async likeTweet(tweetUrl: string) {
let page: Page | null = null;
try {
page = await this.newPage();
await page.goto(tweetUrl, {
waitUntil: 'domcontentloaded',
timeout: 30_000,
});
await this.actLikeTweet(page);
} catch (e) {
}
}
async actLikeTweet(page: Page, isCloseAfterEnd = false) {
try {
this.logger.debug('actLikeTweet:');
await page.waitForTimeout(2000 + (Math.random() + Math.random()) * 3000);
// 1. Cuộn xuống 1000 pixel
await page.mouse.wheel(0, rand(300, 500));
await page.waitForTimeout(rand(2000, 4000));
await page.mouse.wheel(0, rand(300, 500));
this.logger.debug('actLikeTweet:Đã cuộn xuống');
// Nghỉ 2 giây để quan sát
await page.waitForTimeout(rand(2000, 4000));
// 2. Cuộn ngược lên lại 500 pixel
await page.mouse.wheel(0, -1 * 1000);
this.logger.debug('actLikeTweet:Đã cuộn lên');
await page.waitForTimeout(rand(500, 1500));
//like
this.logger.debug('actLikeTweet:Bắt đầu nhấn like');
// Sử dụng selector cụ thể cho bài viết chính (thường có vai trò là article)
const mainTweetLike = page
.locator('article[data-testid="tweet"]').first()
.locator('button[data-testid="like"]');
await mainTweetLike.click();
this.logger.debug('actLikeTweet:Đã like xong');
return true;
} catch (e) {
this.logger.debug(e);
this.logger.error('actLikeTweet: Error:' + e.message);
return false;
} finally {
if (isCloseAfterEnd) {
page.close().catch(() => null);
}
}
}
async postTweet( async postTweet(
account: BrowserAccount, account: BrowserAccount,
text: string, text: string,
@@ -228,7 +290,7 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
.first() .first()
.isVisible() .isVisible()
.catch(() => false); .catch(() => false);
console.log(`postTweet: ${isLoggedIn ? 'LOGGED IN' : 'LOGGED OUT'}`); this.logger.debug(`postTweet: ${isLoggedIn ? 'LOGGED IN' : 'LOGGED OUT'}`);
await page.mouse.wheel(200, rand(300, 800)); await page.mouse.wheel(200, rand(300, 800));
await page.waitForTimeout(rand(2000, 5000)); await page.waitForTimeout(rand(2000, 5000));
@@ -249,7 +311,7 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
} catch { } catch {
await textarea.fill(text); await textarea.fill(text);
} }
console.log(' Nhập tweet xong ...'); this.logger.debug(' Nhập tweet xong ...');
await page.waitForTimeout(2000 + (Math.random() + Math.random()) * 3000); await page.waitForTimeout(2000 + (Math.random() + Math.random()) * 3000);
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
@@ -260,13 +322,13 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
// await page.locator('button[data-testid="tweetButtonInline"]').click({ force: true }); // await page.locator('button[data-testid="tweetButtonInline"]').click({ force: true });
const btn = page.locator('button[data-testid="tweetButtonInline"]'); const btn = page.locator('button[data-testid="tweetButtonInline"]');
const btnBox = await btn.boundingBox(); const btnBox = await btn.boundingBox();
console.log(btnBox); this.logger.debug(btnBox);
console.log('Nhấn Control+Enter ...'); this.logger.debug('Nhấn Control+Enter ...');
// @ts-ignore // @ts-ignore
// await page.mouse.click(btnBox?.x + btnBox.width / 2, btnBox.y + btnBox.height / 2); // await page.mouse.click(btnBox?.x + btnBox.width / 2, btnBox.y + btnBox.height / 2);
await page.keyboard.press('Control+Enter'); await page.keyboard.press('Control+Enter');
console.log('Nhấn Control+Enter done ...'); this.logger.debug('Nhấn Control+Enter done ...');
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
// Chờ request CreateTweet hoàn tất // Chờ request CreateTweet hoàn tất
@@ -296,7 +358,7 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
try { try {
await page.goto(tweetUrl, {waitUntil: 'domcontentloaded', timeout: 30000}); await page.goto(tweetUrl, {waitUntil: 'domcontentloaded', timeout: 30000});
} catch (e) { } catch (e) {
console.log('❌ Load fail'); this.logger.debug('❌ Load fail');
throw e; throw e;
} }
@@ -307,12 +369,12 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
.first() .first()
.isVisible() .isVisible()
.catch(() => false); .catch(() => false);
console.log(`postQuote: ${isLoggedIn ? 'LOGGED IN' : 'LOGGED OUT'}`); this.logger.debug(`postQuote: ${isLoggedIn ? 'LOGGED IN' : 'LOGGED OUT'}`);
// ===== CHECK LOGIN ===== // ===== CHECK LOGIN =====
if (await page.locator('input[name="text"]').count()) { if (await page.locator('input[name="text"]').count()) {
console.log('❌ Cookie die → bị redirect login'); this.logger.error('❌ Cookie die → bị redirect login');
throw new HttpException('❌ Không thấy nút retweet (tweet private?)', 500); throw new HttpException('❌ Không thấy nút retweet (tweet private?)', 500);
@@ -323,15 +385,16 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
await page.waitForTimeout(rand(1000, 5000)); await page.waitForTimeout(rand(1000, 5000));
await page.mouse.wheel(0, rand(300, 800)); await page.mouse.wheel(0, rand(300, 800));
await page.waitForTimeout(rand(4000, 8000)); await page.waitForTimeout(rand(4000, 8000));
await page.evaluate(() => window.scrollTo({top: 0, behavior: 'smooth'})); await page.mouse.wheel(0, -2000);
await page.waitForTimeout(rand(1000, 2000)); await page.waitForTimeout(rand(1000, 2000));
await this.actLikeTweet(page);
// ===== CLICK RETWEET ===== // ===== CLICK RETWEET =====
let retweetBtn = page.locator('[data-testid="retweet"]'); let retweetBtn = page.locator('[data-testid="retweet"]');
if (!(await retweetBtn.count())) { if (!(await retweetBtn.count())) {
console.log('❌ Không thấy nút retweet (tweet private?)'); this.logger.error('❌ Không thấy nút retweet (tweet private?)');
throw new HttpException('❌ Không thấy nút retweet (tweet private?)', 500); throw new HttpException('❌ Không thấy nút retweet (tweet private?)', 500);
} }
@@ -341,7 +404,7 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
try { try {
await page.locator('a[href="/compose/post"]').click({timeout: 2000}); await page.locator('a[href="/compose/post"]').click({timeout: 2000});
} catch { } catch {
console.log('fallback → click by text'); this.logger.debug('fallback → click by text');
await page.locator('a[role="menuitem"]') await page.locator('a[role="menuitem"]')
.filter({hasText: /Quote|Trích dẫn/i}) .filter({hasText: /Quote|Trích dẫn/i})
.click(); .click();
@@ -350,7 +413,7 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
// let quoteBtn = page.locator('[data-testid="retweetWithComment"]'); // let quoteBtn = page.locator('[data-testid="retweetWithComment"]');
// //
// if (!(await quoteBtn.count())) { // if (!(await quoteBtn.count())) {
// console.log('❌ Không thấy nút quote'); // this.logger.debug('❌ Không thấy nút quote');
// return; // return;
// } // }
// //
@@ -367,7 +430,7 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
// const box = page.locator('div[role="textbox"]:visible').first(); // const box = page.locator('div[role="textbox"]:visible').first();
if (!(await box.count())) { if (!(await box.count())) {
console.log('❌ Không thấy textbox'); this.logger.error('❌ Không thấy textbox');
throw new HttpException('❌ Không thấy textbox', 500); throw new HttpException('❌ Không thấy textbox', 500);
} }
@@ -378,34 +441,34 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
// await box.scrollIntoViewIfNeeded(); // await box.scrollIntoViewIfNeeded();
// focus trước khi gõ // focus trước khi gõ
console.log('focus trước khi gõ') this.logger.debug('focus trước khi gõ')
await box.click({delay: rand(50, 150)}); await box.click({delay: rand(50, 150)});
for (let char of content) { for (let char of content) {
await box.type(char, {delay: rand(50, 120)}); await box.type(char, {delay: rand(50, 120)});
} }
console.log('gõ quote xong ...') this.logger.debug('gõ quote xong ...')
await page.waitForTimeout(rand(1000, 2000)); await page.waitForTimeout(rand(1000, 2000));
// ===== POST ===== // ===== POST =====
let postBtn = page.locator('[data-testid="tweetButton"]'); let postBtn = page.locator('[data-testid="tweetButton"]');
console.log('count ...') this.logger.debug('count ...')
if ((await postBtn.count())) { if ((await postBtn.count())) {
console.log('click nút quote ...') this.logger.debug('click nút quote ...')
await postBtn.click({timeout: 7000}).catch(async (e) => { await postBtn.click({timeout: 7000}).catch(async (e) => {
console.log('❌ Nut click khong duoc, thử dùng bàn phím Control+Enter'); this.logger.debug('❌ Nut click khong duoc, thử dùng bàn phím Control+Enter');
await page.keyboard.press('Control+Enter'); await page.keyboard.press('Control+Enter');
}); });
await page.waitForTimeout(rand(4000, 6000)); await page.waitForTimeout(rand(4000, 6000));
console.log('✅ Quoted thành công'); this.logger.debug('✅ Quoted thành công');
} else { } else {
console.log('❌ Không thấy nút post, gọi Ctr + Enter'); this.logger.debug('❌ Không thấy nút post, gọi Ctr + Enter');
await page.keyboard.press('Control+Enter'); await page.keyboard.press('Control+Enter');
await page.waitForTimeout(rand(4000, 6000)); await page.waitForTimeout(rand(4000, 6000));
console.log('✅ Quoted thành công'); this.logger.debug('✅ Quoted thành công');
} }
return {success: true, error: ''}; return {success: true, error: ''};
@@ -420,15 +483,15 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
async postReply(account: BrowserAccount, tweetUrl, content) { async postReply(account: BrowserAccount, tweetUrl, content) {
if (!content) { if (!content) {
console.log(`Nội dung trả lời không có`); this.logger.debug(`Nội dung trả lời không có`);
throw new Error('Nội dung trả lời không có'); throw new Error('Nội dung trả lời không có');
} }
// let ctx = await this.getOrCreateContext(account); // let ctx = await this.getOrCreateContext(account);
// //
// console.log('ctx', ctx); // this.logger.debug('ctx', ctx);
// if (ctx.isClosed()) { // if (ctx.isClosed()) {
// console.log('browser is closeed, reopen'); // this.logger.debug('browser is closeed, reopen');
// ctx = await this.getOrCreateContext(account, false); // ctx = await this.getOrCreateContext(account, false);
// } // }
// const cookies = account.cookies.map((c) => ({ // const cookies = account.cookies.map((c) => ({
@@ -446,15 +509,15 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
// vào tweet // vào tweet
// ===== SAFE GOTO ===== // ===== SAFE GOTO =====
try { try {
console.log(`Mo trang web tweetUrl`); this.logger.debug(`Mo trang web tweetUrl`);
await page.goto(tweetUrl, {waitUntil: 'domcontentloaded', timeout: 30000}); await page.goto(tweetUrl, {waitUntil: 'domcontentloaded', timeout: 30000});
} catch (e) { } catch (e) {
console.log('❌ Load fail'); this.logger.debug('❌ Load fail');
throw e; throw e;
} }
// đợi UI ổn // đợi UI ổn
console.log(`đợi UI ổn...`) this.logger.debug(`đợi UI ổn...`)
await page.waitForSelector('article', {timeout: 7000}); await page.waitForSelector('article', {timeout: 7000});
const isLoggedIn = await page const isLoggedIn = await page
@@ -462,20 +525,22 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
.first() .first()
.isVisible() .isVisible()
.catch(() => false); .catch(() => false);
console.log(`postReply: ${isLoggedIn ? 'LOGGED IN' : 'LOGGED OUT'}`); this.logger.debug(`postReply: ${isLoggedIn ? 'LOGGED IN' : 'LOGGED OUT'}`);
// scroll nhẹ // scroll nhẹ
console.log(`scroll nhẹ ...`) this.logger.debug(`scroll nhẹ ...`)
await page.mouse.wheel(0, 300); await page.mouse.wheel(0, 300);
await page.waitForTimeout(1000 + Math.random() * 2000); await page.waitForTimeout(1000 + Math.random() * 2000);
await this.actLikeTweet(page);
// lấy textbox visible // lấy textbox visible
const box = page.locator('div[role="textbox"]:visible').first(); const box = page.locator('div[role="textbox"]:visible').first();
await box.waitFor({state: 'visible', timeout: 7000}); await box.waitFor({state: 'visible', timeout: 7000});
// focus // focus
console.log(`box focus ...`) this.logger.debug(`box focus ...`)
await box.click(); await box.click();
// nhập content (fallback nếu type fail) // nhập content (fallback nếu type fail)
@@ -485,23 +550,23 @@ export class XBrowserService implements OnModuleInit, OnModuleDestroy {
} catch { } catch {
await box.fill(content); await box.fill(content);
} }
console.log(`nhập nội dung xong ...`) this.logger.debug(`nhập nội dung xong ...`)
await page.waitForTimeout(800 + Math.random() * 1200); await page.waitForTimeout(800 + Math.random() * 1200);
// nút reply // nút reply
const btn = page.locator('[data-testid="tweetButtonInline"]:visible'); const btn = page.locator('[data-testid="tweetButtonInline"]:visible');
if (!(await btn.count())) { if (!(await btn.count())) {
console.log('❌ Không thấy nút reply'); this.logger.debug('❌ Không thấy nút reply');
throw new Error('Không thấy nút reply'); throw new Error('Không thấy nút reply');
// return false; // return false;
} }
await btn.click(); await btn.click();
console.log(`nhấn nút gửi ...`) this.logger.debug(`nhấn nút gửi ...`)
await page.waitForTimeout(3000); await page.waitForTimeout(3000);
console.log('✅ Reply OK'); this.logger.debug('✅ Reply OK');
return {success: true, error: ''}; return {success: true, error: ''};
} catch (err) { } catch (err) {
this.logger.error(`Browser reply failed: ${err.message}`); this.logger.error(`Browser reply failed: ${err.message}`);
+9 -3
View File
@@ -1,7 +1,7 @@
// x-poster.controller.ts // x-poster.controller.ts
import {Body, Controller, Get, HttpException, Post, Query, Req} from '@nestjs/common'; import {Body, Controller, Get, HttpException, Post, Query, Req} from '@nestjs/common';
import {CreateTweetDto, ReplyTweetDto} from './dto/create-tweet.dto'; import {CreateTweetDto, ReplyTweetDto} from './dto/create-tweet.dto';
import {XPosterRouterService, XStrategy} from "./x-poster.router.service"; import {XPosterRouterService} from "./x-poster.router.service";
import {XCookieService} from "./x-cookie.service"; import {XCookieService} from "./x-cookie.service";
import {XApiService} from "./x-api.service"; import {XApiService} from "./x-api.service";
import {XCacheService} from "../x-cache/x-cache.service"; import {XCacheService} from "../x-cache/x-cache.service";
@@ -107,8 +107,14 @@ export class XPosterController {
) { ) {
} }
@Get('verify') @Get('like')
verify() { async likeTweet(@Query('xurl') url: string) {
console.log('xurl==>', url);
if (!url) {
throw new HttpException('xUrl not found', 400);
}
await this.xBrowserService.likeTweet(url);
return 'done';
// const account = { // const account = {
// authToken: process.env.X_COOKIE_AUTH_TOKEN!, // auth_token cookie // authToken: process.env.X_COOKIE_AUTH_TOKEN!, // auth_token cookie
// ct0: process.env.X_COOKIE_CT0!, // ct0: process.env.X_COOKIE_CT0!,
+1 -1
View File
@@ -102,7 +102,7 @@ export class XPosterRouterService {
if (result.success) { if (result.success) {
this.logger.log(`Đã đăng bài thành công`); this.logger.log(`Đã đăng bài thành công`);
await this.notifyService.sendMessageToTele(`Đã đăng bài X thành công`); // await this.notifyService.sendMessageToTele(`Đã đăng bài X thành công`);
return { return {
success: true, success: true,
tweetId: result.tweetId, tweetId: result.tweetId,