server.ts 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /**
  2. * 中央 Webhook 中继服务入口
  3. *
  4. * 启动方式:npm run dev (开发)
  5. * npm start (生产,需先 npm run build)
  6. */
  7. import 'dotenv/config';
  8. import express from 'express';
  9. import cors from 'cors';
  10. import { initRelayDatabase } from './schema.js';
  11. import { relayRoutes } from './routes.js';
  12. import {
  13. getPort,
  14. getDbPath,
  15. getAdminKey,
  16. getUpstreamCallbackSecret,
  17. } from './lib/config.js';
  18. const app = express();
  19. const PORT = getPort();
  20. // 启动前检查关键配置
  21. if (!getAdminKey()) {
  22. console.warn('[Relay] ADMIN_KEY 未设置,管理员接口无法使用。建议运行 openssl rand -hex 32 生成。');
  23. }
  24. if (!getUpstreamCallbackSecret()) {
  25. console.warn('[Relay] UPSTREAM_CALLBACK_SECRET 未设置,全局企微回调入口不可用。');
  26. }
  27. // ---- 中间件 ----
  28. app.use(cors());
  29. app.use(
  30. express.json({
  31. limit: '10mb',
  32. verify: (req: express.Request, _res: express.Response, buf: Buffer) => {
  33. (req as any).rawBody = buf.toString('utf8');
  34. },
  35. }),
  36. );
  37. // ---- 初始化数据库 ----
  38. initRelayDatabase(getDbPath());
  39. console.log('[Relay] 数据库初始化完成');
  40. // ---- 路由 ----
  41. app.use('/api', relayRoutes);
  42. // ---- 全局 404 ----
  43. app.use((_req, res) => {
  44. res.status(404).json({ error: 'Not found' });
  45. });
  46. // ---- 启动 ----
  47. app.listen(PORT, () => {
  48. console.log(`\n========================================`);
  49. console.log(` 企微 Agent Skill 中央 Relay`);
  50. console.log(` http://localhost:${PORT}`);
  51. console.log(`========================================\n`);
  52. console.log(` 健康检查: http://localhost:${PORT}/api/health`);
  53. console.log(` 创建租户: POST http://localhost:${PORT}/api/admin/tenant`);
  54. console.log(` 全局 Webhook: POST http://localhost:${PORT}/api/webhook/ingest`);
  55. console.log(` 兼容 Webhook: POST http://localhost:${PORT}/api/webhook/ingest/:tenantId/:deviceGuid`);
  56. console.log(` 客户端轮询: POST http://localhost:${PORT}/api/poll`);
  57. console.log(` 客户端确认: POST http://localhost:${PORT}/api/ack\n`);
  58. });