Telegram User Gateway

基于 TDLib 的生产级 Telegram 用户账号网关,通过 REST API + Webhook 方式管理多租户多账号的 Telegram 操作

Node.js 20+ NestJS 10 TypeScript 5.3 TDLib 1.8.64+ PostgreSQL / SQLite Redis + BullMQ Docker

目录

01 项目概述

这是一个 生产级 Telegram 用户账号网关。它不是 Telegram Bot API 的封装,而是通过 TDLib(Telegram 的底层 C 语言库)以用户账号身份操作 Telegram。

对外暴露标准 REST API,让上层业务系统可以通过 HTTP 请求操控 Telegram 账号,支持多租户、多账号管理。

典型使用场景

  • 自动化消息发送与群发
  • 群组/频道管理自动化
  • 用户数据采集与分析
  • 消息监控与实时推送
  • 客户服务自动化
  • 跨平台消息桥接

02 技术栈

层次技术选型说明
运行时Node.js 20+ / TypeScript 5.3高性能异步 I/O
Web 框架NestJS 10.x模块化架构 + 依赖注入
数据库PostgreSQL 16 / SQLite (sql.js)生产用 PG,开发用 SQLite
队列Redis 7 + BullMQ可选,通过 .env 关闭
TDLib 绑定prebuilt-tdlib + koffiFFI 调用原生 DLL/SO
线程模型worker_threads每账号一个独立线程
认证JWT + PassportBearer Token 认证
API 文档Swagger自动生成 /api/docs
日志Winston结构化日志
容器化Docker + Docker Compose多阶段构建

03 核心架构

系统采用 三层架构:应用层(NestJS 主线程)、Worker 层(每账号独立线程)、TDLib 层(C 原生库)。

┌─────────────────────────────────────────────────────────┐ │ 外部业务系统 │ │ (通过 REST API 调用) │ └──────────────────────┬──────────────────────────────────┘ │ HTTP ┌──────────────────────▼──────────────────────────────────┐ │ NestJS 应用层 (主线程) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ │ │ 认证模块 │ │ 账号模块 │ │ 消息模块 │ │Webhook │ │ │ │ Auth │ │ Accounts │ │ Messages │ │ 模块 │ │ │ └──────────┘ └──────────┘ └──────────┘ └─────────┘ │ │ │ │ │ TdlibClientManagerService │ │ (Worker 线程管理器) │ └────────────────┬─────────────────────────────────────────┘ │ worker_threads (postMessage) ┌────────────────▼─────────────────────────────────────────┐ │ Worker 线程层 (每 TG 账号一个) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Worker #1 │ │ Worker #2 │ │ Worker #3 │ │ │ │ (tdjson │ │ (tdjson │ │ (tdjson │ │ │ │ FFI 调用) │ │ FFI 调用) │ │ FFI 调用) │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └────────────────┬─────────────────────────────────────────┘ │ ┌────────────────▼─────────────────────────────────────────┐ │ TDLib (C 原生库) │ │ tdjson.dll / libtdjson.so │ └──────────────────────────────────────────────────────────┘

请求-响应匹配机制

每个请求通过 UUID @extra 标记,存入 pendingRequests Map。Worker 处理完成后通过相同的 @extra 回传,主线程匹配后 resolve/reject 对应的 Promise。超时 30 秒自动 reject。

04 目录结构

项目根目录

telegram-getway/ ├── .env # 运行时配置 ├── .env.example # 配置模板 ├── package.json # 依赖与脚本 ├── tsconfig.json # TypeScript 配置 ├── nest-cli.json # NestJS CLI 配置 ├── src/ # 源代码 ├── data/ # SQLite 数据库 ├── tdlib_data/ # TDLib 数据(每账号子目录) ├── uploads/ # 文件上传存储 ├── docker/ # Docker 配置 │ ├── Dockerfile # 多阶段构建 │ └── docker-compose.yml # PG + Redis + App └── test/ # 测试文件

源代码目录 (src/)

src/ ├── main.ts # 应用入口 ├── app.module.ts # 根模块(注册 15 个子模块) ├── config/ # 配置模块 │ ├── app.config.ts # 应用配置 │ ├── database.config.ts # 数据库配置(PG/SQLite) │ ├── redis.config.ts # Redis 配置 │ └── rate-limit.config.ts # 速率限制配置 ├── common/ # 通用组件 │ ├── decorators/ # 装饰器(@CurrentUser, @Tenant) │ ├── errors/ # 异常类 + 60+ 错误码 │ ├── filters/ # 全局异常过滤器 │ ├── guards/ # JWT 守卫 + 租户守卫 │ ├── interceptors/ # 响应格式 + 审计日志 │ └── pipes/ # 参数验证管道 ├── database/ # 数据库层 │ ├── entities/ # 16 个 TypeORM 实体 │ └── migrations/ # 数据库迁移 ├── modules/ # 15 个业务模块 │ ├── auth/ # 认证(注册/登录/JWT) │ ├── tenants/ # 租户管理 │ ├── tg-accounts/ # TG 账号 CRUD │ ├── tg-auth/ # TG 授权流程 │ ├── tdlib/ # TDLib 核心管理器 │ ├── tg-proxies/ # 代理管理 │ ├── tg-chats/ # 聊天模块 │ ├── tg-dialogs/ # 对话模块 │ ├── tg-contacts/ # 联系人模块 │ ├── tg-messages/ # 消息发送/编辑/搜索 │ ├── tg-groups/ # 群组管理 │ ├── tg-channels/ # 频道管理 │ ├── tg-files/ # 文件上传/下载 │ ├── tg-webhooks/ # Webhook 订阅与投递 │ ├── tg-rate-limit/ # 速率限制 │ ├── tg-audit/ # 审计日志 │ └── admin/ # 管理(健康检查/指标) └── workers/ # Worker 线程 ├── tdlib-client.worker.ts # TDLib 客户端(核心) ├── send-message.worker.ts # 消息发送 BullMQ ├── file-download.worker.ts# 文件下载 └── webhook-delivery.worker.ts # Webhook 投递

05 核心模块详解

5.1 TDLib 客户端管理器

src/modules/tdlib/tdlib-client-manager.service.ts — 整个系统的心脏

属性类型作用
workersMap<string, Worker>accountId → Worker 线程映射
pendingRequestsMap<string, PendingRequest>UUID → Promise 映射(请求-响应匹配)
accountAuthStateMap<string, string>追踪每个账号的授权状态
clientIdToAccountIdMap<number, string>clientId → accountId 反向查找

核心方法:

5.2 TDLib Worker

src/workers/tdlib-client.worker.ts — 每个 TG 账号的独立线程

关键兼容性:TDLib 1.8.64+ 使用 FLAT 格式,setTdlibParameters 参数不再包裹在 parameters 对象里。

启动流程:

1
loadTdlib() — 通过 koffi 加载原生 tdjson DLL/SO(支持自动路径检测)
↓
2
td_json_client_create() — 创建 TDLib 客户端实例
↓
3
配置代理 — 支持 SOCKS5 / HTTP / MTProto 代理
↓
4
mainLoop() — setImmediate 递归事件循环,非阻塞轮询 TDLib

事件循环逻辑:

  1. 处理主线程消息队列(发送请求到 TDLib)
  2. td_json_client_receive(timeout=0.1) — 非阻塞轮询响应
  3. processResponse() — 处理 TDLib 响应,自动处理授权状态机
  4. setImmediate(mainLoop) — 让出事件循环,继续下一轮

5.3 账号授权模块

src/modules/tg-auth/tg-auth.service.ts — 处理 Telegram 完整授权流程

API 端点方法TDLib 调用状态转换
POST /auth/phonesetPhoneNumber()setAuthenticationPhoneNumber→ WAITING_CODE
POST /auth/codesubmitCode()checkAuthenticationCode→ READY / WAITING_PASSWORD
POST /auth/passwordsubmitPassword()checkAuthenticationPassword→ READY
POST /auth/logoutlogout()logOut→ CREATED
POST /auth/resendresendCode()resendAuthenticationCode—

5.4 消息模块

src/modules/tg-messages/tg-messages.service.ts — 双模式消息发送

队列模式(Redis 启用)

  • BullMQ 异步发送
  • 3 次指数退避重试
  • TgSendJob 持久化追踪
  • 失败回退到直接模式

直接模式(Redis 禁用)

  • 同步调用 TDLib
  • 无重试机制
  • 简单直接
  • 适合开发/轻量场景

支持的操作:

操作TDLib 方法说明
sendMessagesendMessage发送文本/媒体消息
editMessageeditMessageText编辑已发消息
forwardMessageforwardMessages转发消息
deleteMessagedeleteMessages删除消息(可选 revoke)
searchMessagessearchChatMessages搜索聊天记录

5.5 Webhook 模块

src/modules/tg-webhooks/tg-webhooks.service.ts — 事件推送机制

06 数据库实体关系

共 16 个实体,覆盖 Telegram 操作的所有数据面。

Tenant (租户) ├── 1:N → User (系统用户: email + password) └── 1:N → TgAccount (TG账号) ├── 1:N → TgAccountProxyBinding → TgProxy (代理绑定) ├── 1:N → TgChat (聊天) ├── 1:N → TgMessage (消息) ├── 1:N → TgContact (联系人) ├── 1:N → TgGroup (群组) ├── 1:N → TgSendJob (发送任务) ├── 1:N → TgFile (文件) ├── 1:N → TgWebhookSubscription (Webhook订阅) │ └── 1:N → TgWebhookDelivery (投递记录) └── 1:N → TgAuditLog (审计日志) 独立实体: TgRawUpdate (原始更新), TgRateLimitEvent (速率事件)
实体表名关键字段
Tenanttenantsname, maxAccounts, isActive
Userusersemail, passwordHash, tenantId
TgAccounttg_accountsphoneNumber, status, tenantId, tdlibClientId
TgProxytg_proxiestype, host, port, username, password
TgChattg_chatstgChatId, title, type, accountId
TgMessagetg_messagestgMessageId, content, chatId, accountId
TgSendJobtg_send_jobsbullJobId, status, payload, accountId
TgWebhookSubscriptiontg_webhook_subscriptionsurl, events, secret, isActive
TgWebhookDeliverytg_webhook_deliveriesurl, payload, status, attempt

07 账号状态机

TG 账号的生命周期通过状态机管理:

CREATED → WAITING_TDLIB → WAITING_PHONE → WAITING_CODE → WAITING_PASSWORD → READY
↓ 异常
ERROR / DISABLED
状态含义触发条件
CREATED已创建,未启动创建 TG 账号记录
WAITING_TDLIBTDLib 初始化中调用 startClient()
WAITING_PHONE等待提交手机号TDLib 就绪
WAITING_CODE等待验证码提交手机号成功
WAITING_PASSWORD等待 2FA 密码提交验证码后检测到 2FA
READY已授权,可用授权流程完成
ERROR出错任何步骤失败
DISABLED已禁用手动禁用或登出

08 API 端点总览

路径方法功能认证
/api/auth/registerPOST用户注册公开
/api/auth/loginPOST用户登录(返回 JWT)公开
/api/admin/healthGET健康检查公开
/api/admin/metricsGET应用指标JWT
/api/admin/statusGETTDLib 状态JWT
/api/tenantsCRUD租户管理JWT
/api/tg-accountsCRUDTG 账号管理JWT + 租户
/api/tg-accounts/:id/startPOST启动 TDLib 客户端JWT + 租户
/api/tg-accounts/:id/stopPOST停止 TDLib 客户端JWT + 租户
/api/tg-accounts/:id/auth/phonePOST提交手机号JWT + 租户
/api/tg-accounts/:id/auth/codePOST提交验证码JWT + 租户
/api/tg-accounts/:id/auth/passwordPOST提交 2FA 密码JWT + 租户
/api/tg-accounts/:id/chatsGET获取聊天列表JWT + 租户
/api/tg-accounts/:id/messagesPOST发送消息JWT + 租户
/api/tg-accounts/:id/messages/searchPOST搜索消息JWT + 租户
/api/tg-accounts/:id/webhooksCRUDWebhook 订阅管理JWT + 租户
/api/docsGETSwagger API 文档公开

09 安全与多租户

认证机制

  • JWT 全局守卫:APP_GUARD 注册 JwtAuthGuard
  • 所有路由默认需要认证
  • 公开路由通过 @Public() 装饰器标记
  • 密码使用 bcrypt 哈希存储

租户隔离

  • x-tenant-id header + TenantGuard
  • 每个请求都绑定到特定租户
  • 租户有 maxAccounts 限制(默认 5)
  • 数据完全隔离,不可跨租户访问

审计日志

错误码体系

定义了 60+ 错误码,覆盖所有异常场景:

  • GENERAL: INTERNAL_ERROR, VALIDATION_ERROR, NOT_FOUND...
  • TENANT: TENANT_NOT_FOUND, TENANT_DISABLED
  • AUTH: INVALID_CREDENTIALS, TOKEN_EXPIRED
  • TG_ACCOUNT: TG_ACCOUNT_NOT_FOUND, TG_ACCOUNT_LIMIT_REACHED
  • TDLib: TDLIB_CLIENT_NOT_FOUND, TDLIB_ERROR
  • WEBHOOK: WEBHOOK_NOT_FOUND, WEBHOOK_DELIVERY_FAILED

10 配置模式

开发模式(当前)

DB_TYPEsqlite
REDIS_ENABLEDfalse
TDLIB_PATH自动检测
消息发送直接模式

无需外部依赖,开箱即用

生产模式

DB_TYPEpostgres
REDIS_ENABLEDtrue
TDLIB_PATH指定路径
消息发送队列模式

需要 PostgreSQL + Redis 服务

关键环境变量

变量说明默认值
PORT服务端口3000
DB_TYPE数据库类型 (postgres/sqlite)postgres
TG_API_IDTelegram API ID—
TG_API_HASHTelegram API Hash—
JWT_SECRETJWT 签名密钥—
REDIS_ENABLED是否启用 Redistrue
TDLIB_PATHTDLib 库路径自动检测
MAX_FILE_SIZE最大上传文件大小200MB

11 完整调用流程示例

1
POST /api/auth/register — 注册系统用户
{"email": "admin@example.com", "password": "***"}
↓
2
POST /api/auth/login — 登录获取 JWT Token
{"token": "eyJhbGciOiJIUzI1NiIs..."}
↓
3
POST /api/tenants — 创建租户
Header: x-tenant-id: xxx
↓
4
POST /api/tg-accounts — 创建 TG 账号(自动启动 TDLib Worker)
↓
5
POST /api/tg-accounts/:id/auth/phone — 提交手机号
{"phoneNumber": "+8613800138000"}
↓
6
POST /api/tg-accounts/:id/auth/code — 提交验证码
{"code": "12345"}
↓
7
POST /api/tg-accounts/:id/messages — 发送消息
{"chatId": 123456, "text": "Hello!"}
↓
8
POST /api/tg-accounts/:id/webhooks — 创建 Webhook 订阅
{"url": "https://example.com/hook", "events": ["newMessage"]}

12 构建与部署

本地开发

# 安装依赖
npm install

# 开发模式(热重载)
npm run start:dev

# 访问 Swagger 文档
http://localhost:3000/api/docs

生产构建

# 编译 TypeScript
npm run build

# 启动生产服务
npm run start:prod

# 运行数据库迁移
npm run migration:run

Docker 部署

# 一键启动(PostgreSQL + Redis + App)
docker-compose -f docker/docker-compose.yml up -d

# 查看日志
docker-compose -f docker/docker-compose.yml logs -f app

测试

# 单元测试
npm run test

# 端到端测试
npm run test:e2e