This commit is contained in:
NAME
2026-05-15 00:22:30 +00:00
parent b57c9aa0bd
commit 65768643e0
8 changed files with 998 additions and 1313 deletions
+2
View File
@@ -58,3 +58,5 @@ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
dist dist
.idea .idea
dist.zip dist.zip
data/*
+1
View File
@@ -34,6 +34,7 @@
"class-validator": "^0.15.1", "class-validator": "^0.15.1",
"cookie": "^1.1.1", "cookie": "^1.1.1",
"https-proxy-agent": "^9.0.0", "https-proxy-agent": "^9.0.0",
"keyv": "^5.6.0",
"lodash": "^4.18.1", "lodash": "^4.18.1",
"playwright": "^1.59.1", "playwright": "^1.59.1",
"playwright-extra": "^4.3.6", "playwright-extra": "^4.3.6",
+943 -1298
View File
File diff suppressed because it is too large Load Diff
+5 -2
View File
@@ -2,12 +2,15 @@ import {Controller, Get, Post} from '@nestjs/common';
import {AppService} from './app.service'; import {AppService} from './app.service';
import {XCookieAccountDto} from "./x-poster/dto/x-cookie-account.dto"; import {XCookieAccountDto} from "./x-poster/dto/x-cookie-account.dto";
import {XPosterRouterService} from "./x-poster/x-poster.router.service"; import {XPosterRouterService} from "./x-poster/x-poster.router.service";
import {Context} from "node:vm";
import {XCacheService} from "./x-cache/x-cache.service";
@Controller() @Controller()
export class AppController { export class AppController {
constructor( constructor(
private readonly appService: AppService, private readonly appService: AppService,
private readonly xPosterRouterService: XPosterRouterService, private readonly xPosterRouterService: XPosterRouterService,
private readonly cache: XCacheService
) { ) {
} }
@@ -16,8 +19,8 @@ export class AppController {
return this.xPosterRouterService.verifyCookie(); return this.xPosterRouterService.verifyCookie();
} }
@Post('/set-x-cookies') @Get('/x')
setXCookies(dto: XCookieAccountDto) { setXCookies(dto: XCookieAccountDto) {
return this.cache.getCacheTwRefreshToken();
} }
} }
+7 -3
View File
@@ -5,8 +5,12 @@ import {SqsModule} from "./sqs-module/sqs.module";
import {XPosterModule} from "./x-poster/x-poster.module"; import {XPosterModule} from "./x-poster/x-poster.module";
import {ConfigModule} from "@nestjs/config"; import {ConfigModule} from "@nestjs/config";
import {CacheModule} from "@nestjs/cache-manager"; import {CacheModule} from "@nestjs/cache-manager";
import KeyvRedis from "@keyv/redis";
import {XbotFollowModule} from "./xbot-follow/xbot-follow.module"; import {XbotFollowModule} from "./xbot-follow/xbot-follow.module";
import * as path from 'path';
import {XCacheService} from "./x-cache/x-cache.service";
import KeyvRedis from "@keyv/redis";
console.log(`sqlite://${path.join(process.cwd(), 'cache.sqlite')}`)
@Module({ @Module({
imports: [ imports: [
@@ -20,7 +24,7 @@ import {XbotFollowModule} from "./xbot-follow/xbot-follow.module";
isGlobal: true, isGlobal: true,
useFactory: () => ({ useFactory: () => ({
stores: [ stores: [
new KeyvRedis(`redis://127.0.0.1:6379/1`) new KeyvRedis(process.env.REDIS_URL)
], ],
}), }),
}), }),
@@ -29,7 +33,7 @@ import {XbotFollowModule} from "./xbot-follow/xbot-follow.module";
XbotFollowModule, XbotFollowModule,
], ],
controllers: [AppController], controllers: [AppController],
providers: [AppService], providers: [AppService, XCacheService,],
}) })
export class AppModule { export class AppModule {
} }
+4
View File
@@ -2,8 +2,12 @@ import {NestFactory} from '@nestjs/core';
import {AppModule} from './app.module'; import {AppModule} from './app.module';
import {SqsPosterWorker} from "./sqs-module/sqs.poster.worker"; import {SqsPosterWorker} from "./sqs-module/sqs.poster.worker";
import {DocumentBuilder, SwaggerModule} from "@nestjs/swagger"; import {DocumentBuilder, SwaggerModule} from "@nestjs/swagger";
import fs from 'fs';
async function bootstrap() { async function bootstrap() {
fs.mkdirSync('./data', { recursive: true });
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule);
// Cấu hình Swagger // Cấu hình Swagger
+1 -1
View File
@@ -120,7 +120,7 @@ export class SqsPosterWorker {
let sendSuccess = false; let sendSuccess = false;
if (publishTo.includes(SUPPORT_SOCIAL_PROVIDERS.FB)) { if (publishTo.includes(SUPPORT_SOCIAL_PROVIDERS.FB)) {
this.logger.log(`==> doPostTweet publish to fb`); this.logger.log(`==> doPostTweet publish to fb`);
await this.facebookApi.postToPage(text); await this.facebookApi.postToPage(text, '', false);
await this.notifyService.sendMessageToTele(`Post to FB success`); await this.notifyService.sendMessageToTele(`Post to FB success`);
sendSuccess = true; sendSuccess = true;
} }
+35 -9
View File
@@ -1,14 +1,15 @@
// src/modules/social/facebook-api.service.ts // src/modules/social/facebook-api.service.ts
import {HttpException, HttpStatus, Injectable} from '@nestjs/common'; import {HttpException, HttpStatus, Injectable, Logger} from '@nestjs/common';
import axios from 'axios'; import axios from 'axios';
@Injectable() @Injectable()
export class FacebookApi { export class FacebookApi {
private logger = new Logger('FacebookApi');
private readonly fbBaseUrl = 'https://graph.facebook.com/v19.0'; private readonly fbBaseUrl = 'https://graph.facebook.com/v19.0';
private readonly pageAccessToken = process.env.FB_PAGE_ACCESS_TOKEN; private readonly pageAccessToken = process.env.FB_PAGE_ACCESS_TOKEN;
private readonly pageId = process.env.FB_PAGE_ID; private readonly pageId = process.env.FB_PAGE_ID;
async postToPage(content: string, imageUrl?: string) { async postToPage(content: string, imageUrl?: string, throwEx = true) {
// console.log('postToPage==>', content, imageUrl); // console.log('postToPage==>', content, imageUrl);
try { try {
let url = `${this.fbBaseUrl}/${this.pageId}/feed`; let url = `${this.fbBaseUrl}/${this.pageId}/feed`;
@@ -25,14 +26,39 @@ export class FacebookApi {
const response = await axios.post(url, params); const response = await axios.post(url, params);
//response.data= { id: '1010286162176053_122107818902775551' } //response.data= { id: '1010286162176053_122107818902775551' }
return response.data; // Trả về ID bài viết nếu thành công // return response.data; // Trả về ID bài viết nếu thành công
return {
success: true,
postId: response.data,
}
} catch (error) { } catch (error) {
console.log('Lỗi khi đăng bài lên FB'); this.logger.error('Lỗi khi đăng bài lên FB');
console.log(error.message); this.logger.error(error.message);
throw new HttpException( // Kiểm tra xem Facebook có trả về response lỗi không
error.response?.data || 'Lỗi khi đăng bài lên FB', let fbErrormessage = error.message;;
HttpStatus.BAD_REQUEST, if (error.response && error.response.data) {
); const fbError = error.response.data.error;
fbErrormessage = fbError.constructor
this.logger.error('--- LỖI FACEBOOK API ---');
this.logger.error('Message:', fbErrormessage);
this.logger.error('Code:', fbError.code);
this.logger.error('Subcode:', fbError.error_subcode);
this.logger.error('FB Trace ID:', fbError.fbtrace_id);
} else {
// Lỗi do mạng hoặc cấu hình Axios sai
this.logger.error('Lỗi hệ thống/mạng:', error.message);
}
if (throwEx) {
throw new HttpException(
fbErrormessage || 'Fb Lỗi khi đăng bài lên FB',
HttpStatus.BAD_REQUEST,
);
}
return {
success: false,
postId: 0,
error: error.message,
}
} }
} }
} }