server.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import express from 'express';
  2. import { readFileSync } from 'node:fs';
  3. const cors = require('cors');
  4. import { createTikHubCustomizeRoutes } from './modules/fmode-tikhub-server/src/mod';
  5. // import { createPinterestRouter } from './modules/fmode-brightdata-server/src/index';
  6. const Parse = require('parse/node');
  7. Parse.initialize('hb-voc');
  8. Parse.serverURL = 'https://partyvoc.com/parse';
  9. Parse.masterKey = 'hb2026pallt';
  10. // @ts-ignore
  11. globalThis.Parse = Parse;
  12. // 获取配置
  13. function getConfig() {
  14. try {
  15. const configPath = process.env.NODE_ENV === 'test' ? './config.test.json' : './config.json';
  16. const configContent = readFileSync(configPath, 'utf-8');
  17. return JSON.parse(configContent);
  18. } catch (error: unknown) {
  19. const errorMessage = error instanceof Error ? error.message : 'Unknown error';
  20. console.warn('Config file not found, using defaults:', errorMessage);
  21. return {
  22. parse: {
  23. port: 3000,
  24. appId: 'hb-voc',
  25. serverURL: 'https://partyvoc.com/parse'
  26. }
  27. };
  28. }
  29. }
  30. // 初始化 Express 应用
  31. const app = express();
  32. // 中间件配置
  33. app.use(cors());
  34. app.use(express.json());
  35. app.use(express.urlencoded({ extended: true }));
  36. // 日志中间件
  37. app.use((req: any, res: any, next: () => void) => {
  38. console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`);
  39. next();
  40. });
  41. // 健康检查端点
  42. app.get('/health', (req: any, res: any) => {
  43. res.json({
  44. status: 'healthy',
  45. timestamp: new Date().toISOString(),
  46. uptime: process.uptime()
  47. });
  48. });
  49. // 根路由
  50. app.get('/', (req: any, res: any) => {
  51. res.json({
  52. message: 'Fmode Server - Gongzuo API',
  53. version: '1.0.0',
  54. timestamp: new Date().toISOString(),
  55. endpoints: ['/api', '/health', '/api/tikhub']
  56. });
  57. });
  58. // 挂载 TikHub 模块路由
  59. app.use('/api/tikhub', createTikHubCustomizeRoutes({
  60. serverURL: 'https://server.fmode.cn/thapi/v1',
  61. apiKey: 'tKIbAsEM8X+GmE2vHqGW7D/ICwK1Q5V4viKFrWiPB6HholGdLFqZJmmyNw=='
  62. }));
  63. // 挂载 Pinterest 模块路由
  64. // app.use('/api/pinterest', createPinterestRouter());
  65. // 404 处理
  66. app.use((req: any, res: any) => {
  67. res.status(404).json({
  68. message: 'Not Found',
  69. path: req.path,
  70. method: req.method
  71. });
  72. });
  73. // 错误处理中间件
  74. app.use((err: any, req: any, res: any, next: any) => {
  75. console.error('Error:', err);
  76. res.status(500).json({
  77. message: 'Internal Server Error',
  78. error: err.message
  79. });
  80. });
  81. // 启动服务器
  82. async function startServer() {
  83. const config = getConfig();
  84. const PORT = process.env.PORT || config.parse?.port || 3000;
  85. app.listen(PORT, () => {
  86. console.log('\n' + '='.repeat(60));
  87. console.log('🚀 Fmode Server - HB Started');
  88. console.log('='.repeat(60));
  89. console.log(`Timestamp: ${new Date().toISOString()}`);
  90. console.log('='.repeat(60) + '\n');
  91. });
  92. }
  93. // 优雅关闭
  94. process.on('SIGTERM', () => {
  95. console.log('\n📛 SIGTERM signal received: closing HTTP server');
  96. process.exit(0);
  97. });
  98. process.on('SIGINT', () => {
  99. console.log('\n📛 SIGINT signal received: closing HTTP server');
  100. process.exit(0);
  101. });
  102. // 启动服务器
  103. startServer().catch(err => {
  104. console.error('Failed to start server:', err);
  105. process.exit(1);
  106. });