项目文件夹

文件
wehub-resource-sync 7ac9a73160
CI / Test (PostgreSQL migrations) (push) Has been cancelled
CI / Dashboard (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Build (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
docs: make Chinese README the default
2026-07-13 10:54:13 +00:00

415 行
16 KiB
Markdown

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
<!-- WEHUB_ZH_README -->
> [!NOTE]
> 本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
> [English](./README.en.md) · [原始项目](https://github.com/rmyndharis/OpenWA) · [上游 README](https://github.com/rmyndharis/OpenWA/blob/HEAD/README.md)
> 原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。
<p align="center">
<img src="docs/logo/openwa_logo.webp" alt="OpenWA Logo" width="200"/>
</p>
<h1 align="center">OpenWA</h1>
<p align="center">
<strong>开源 WhatsApp API 网关</strong>
</p>
<p align="center">
<a href="#-features">特性</a> •
<a href="#-quick-start">快速开始</a> •
<a href="#-documentation">文档</a> •
<a href="#-api-examples">API</a> •
<a href="#-contributing">贡献</a>
</p>
<p align="center">
<a href="https://github.com/rmyndharis/OpenWA/actions/workflows/ci.yml"><img src="https://github.com/rmyndharis/OpenWA/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"/></a>
<img src="https://img.shields.io/github/package-json/v/rmyndharis/OpenWA?label=version&color=blue" alt="Version"/>
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"/>
<img src="https://img.shields.io/badge/node-22_LTS-brightgreen.svg" alt="Node"/>
<img src="https://img.shields.io/badge/NestJS-11.x-red.svg" alt="NestJS"/>
<img src="https://img.shields.io/badge/docker-ready-blue.svg" alt="Docker"/>
<img src="https://img.shields.io/badge/TypeScript-5.x-3178C6.svg" alt="TypeScript"/>
</p>
---
## ✨ 为什么选择 OpenWA?
**OpenWA** 是一款免费、开源的 WhatsApp API 网关(Gateway),面向需要完全掌控消息基础设施、且不愿被厂商锁定或遭遇隐藏付费墙的开发者。
基于**可插拔架构(Pluggable Architecture**,OpenWA 允许你通过配置更换数据库引擎(SQLite/PostgreSQL)、存储后端(Local/S3)和缓存层(Memory/Redis),而无需修改应用代码中的任何一行。
| | |
| ----------------------------- | ------------------------------------------------------------ |
| 🔓 **100% 开源** | 无许可费用、无功能锁定、可访问完整源代码 |
| 🏗️ **可插拔架构** | 通过配置切换数据库、存储和缓存适配器 |
| 🖥️ **完整仪表盘** | 现代化的 React UI,用于管理会话、Webhook 和 API 密钥 |
| 🔹 **多会话就绪** | 在单个实例上并发运行多个 WhatsApp 会话 |
| 🐳 **原生 Docker 支持** | 开箱即用,可用于生产环境,零配置 |
| 🔗 **n8n 集成** | 用于工作流自动化的社区节点 |
| 🧩 **社区适配器** | 第三方集成(例如 ioBroker)— 参见 [文档](./docs/23-community-integrations.md) |
---
## 🎯 特性
### 核心特性
| 特性 | 状态 | 描述 |
| ------------- | ------ | ------------------------------------ |
| REST API | ✅ | 通过 HTTP 端点提供完整的 WhatsApp API |
| 多会话 | ✅ | 管理多个 WhatsApp 账户 |
| Webhook | ✅ | 实时事件,支持 HMAC 签名及可选的智能预分发过滤器 |
| Web 仪表盘 | ✅ | 可视化管理界面 |
| API 密钥认证 | ✅ | 安全的 API 身份验证 |
| Swagger 文档 | ✅ | 交互式 API 文档 |
### 消息
| 特性 | 状态 | 描述 |
| ----------------- | ------ | -------------------------------- |
| 文本消息 | ✅ | 发送/接收文本消息 |
| 媒体消息 | ✅ | 图片、视频、文档、音频 |
| 消息回应 | ✅ | 使用表情符号回应消息 |
| 批量消息 | ✅ | 向多个收件人发送 |
| 消息状态 | ✅ | 跟踪送达和已读回执 |
### 高级功能
| 特性 | 状态 | 描述 |
| ------------------- | ------ | ---------------------------------- |
| 群组 API | ✅ | 创建、管理群组并发送消息 |
| 频道/Newsletter | ✅ | 支持 WhatsApp 频道 |
| 标签管理 | ✅ | 使用标签整理聊天 |
| 代理支持 | ✅ | 按会话配置代理 |
| 速率限制 | ✅ | 可配置的请求限制 |
| CIDR 白名单 | ✅ | 基于 IP 的访问控制 |
| 审计日志 | ✅ | 跟踪所有 API 操作 |
### 基础设施
| 特性 | 状态 | 描述 |
| ---------------- | ------ | ------------------------------ |
| SQLite | ✅ | 零配置嵌入式数据库 |
| PostgreSQL | ✅ | 生产级数据库 |
| Redis 缓存 | ✅ | 可选的性能缓存 |
| S3/MinIO 存储 | ✅ | 可扩展的媒体存储 |
| Docker | ✅ | 一条命令完成部署 |
| 健康检查 | ✅ | 适用于 Kubernetes 的探针 |
| 数据迁移 | ✅ | 在后端之间导出/导入 |
---
## 🚀 快速开始
### 方案 ADocker(推荐)
```bash
# Clone and start
git clone https://github.com/rmyndharis/OpenWA.git
cd OpenWA
docker compose -f docker-compose.dev.yml up -d
# Access (the dashboard is bundled into the API image and served on the same port)
# Dashboard: http://localhost:2785
# API: http://localhost:2785/api
# Swagger: http://localhost:2785/api/docs
```
> **使用 Podman 而非 Docker?**
> Podman 无 root 模式需要 socket 正在运行,并设置 `DOCKER_HOST`
>
> ```bash
> systemctl --user start podman.socket
> systemctl --user enable podman.socket
> export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock
> ```
>
> 将 `export` 这一行添加到你的 `~/.bashrc` 中,以使其永久生效。
### 方案 B:本地开发
```bash
# Clone repository
git clone https://github.com/rmyndharis/OpenWA.git
cd OpenWA
# Install dependencies (includes dashboard)
npm install
# Start API + Dashboard (config is auto-generated on first run)
npm run dev
# Access (in dev the dashboard runs on the Vite server with hot reload)
# Dashboard: http://localhost:2886
# API: http://localhost:2785/api
# Swagger: http://localhost:2785/api/docs
```
---
## 🔒 安全架构
### Docker Socket 代理
生产环境技术栈绝不会将 `/var/run/docker.sock` 直接暴露给应用容器。相反,一个专用的 `docker-proxy` 边车(sidecar,基于 [`tecnativa/docker-socket-proxy`](https://github.com/Tecnativa/docker-socket-proxy)))作为访问 Docker 守护进程的唯一网关:
```
openwa-api ──TCP 2375──▶ docker-proxy ──unix──▶ /var/run/docker.sock
```
仅启用容器编排所需的操作(`CONTAINERS``IMAGES``VOLUMES``INFO``PING``POST``DELETE`)。应用通过 `DOCKER_HOST=tcp://docker-proxy:2375` 环境变量连接,`DockerService` 会自动检测该变量。
---
## 🔒 安全架构
### 非 root 容器执行
生产镜像绝不会以 root 身份运行 Node.js 进程。启动时,容器遵循以下链路:
```
dumb-init (PID 1)
└─ docker-entrypoint.sh (root — fixes named-volume ownership via chown)
└─ gosu openwa node dist/main (drops to the openwa user)
```
- **dumb-init** 作为 PID 1,转发信号(SIGTERM 等)以实现优雅关闭。
- **docker-entrypoint.sh** 仅以 root 身份运行足够长的时间,以便 `chown` 命名卷挂载点,使 `openwa` 用户可以写入它们。
- **gosu** 执行基于 `exec` 的干净权限降级 — 不使用 `su``sudo` 包装器,因此 node 进程是 dumb-init 的直接子进程。
命名卷(例如 `openwa-data`)在每次启动时都会自动修正所有权,因此在创建卷后无需手动执行 `chown` 步骤。
---
## 🏭 生产部署
生产环境请使用主 `docker-compose.yml`,并可按需启用可选服务:
```bash
# Basic production (SQLite, local storage)
docker compose up -d
# With PostgreSQL database
docker compose --profile postgres up -d
# Full stack (PostgreSQL, Redis, MinIO)
docker compose --profile full up -d
```
| 配置方案(Profile | 服务 |
| ---------- | --------------------- |
| `postgres` | PostgreSQL 数据库 |
| `redis` | Redis 缓存 |
| `minio` | S3 兼容存储 |
| `full` | 上述所有服务 |
> Dashboard 已打包进 API 镜像,由 NestJS 在 API 端口提供服务,因此无需 profile —— 只要 `openwa-api` 运行,它就始终可用。如需 TLS/公网暴露,请在前方放置你自己的反向代理(nginx、Caddy、云负载均衡器或 k8s Ingress);参见 `docs/12-troubleshooting-faq.md` 中的 nginx 示例。
> **开发环境 vs 生产环境**
>
> - 开发环境(`docker-compose.dev.yml`):SQLite、本地存储,API 提供打包的 dashboard
> - 生产环境(`docker-compose.yml`):可配置数据库,通过 profile 启用可选服务
>
> 官方 GHCR 镜像以多架构 manifest 形式发布:
> - `linux/amd64`
> - `linux/arm64`
## 🔌 端口
| 服务 | 端口 | 说明 |
| --------------- | --------------- | --------------------------------------------- |
| API & Dashboard | `2785` | REST API + 打包的 Web 仪表盘(同一端口) |
| Swagger | `2785/api/docs` | 交互式 API 文档 |
| Dashboard (dev) | `2886` | 带热重载的 Vite 开发服务器(`npm run dev` |
---
## 📡 API 示例
### 创建会话
```bash
curl -X POST http://localhost:2785/api/sessions \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"name": "my-bot"}'
```
### 启动会话并获取二维码
```bash
# Start the session
curl -X POST http://localhost:2785/api/sessions/{sessionId}/start \
-H "X-API-Key: YOUR_API_KEY"
# Get QR code (scan with WhatsApp)
curl http://localhost:2785/api/sessions/{sessionId}/qr \
-H "X-API-Key: YOUR_API_KEY"
```
### 发送消息
```bash
curl -X POST http://localhost:2785/api/sessions/{sessionId}/messages/send-text \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"chatId": "628123456789@c.us",
"text": "Hello from OpenWA!"
}'
```
### 配置 Webhook
```bash
curl -X POST http://localhost:2785/api/sessions/{sessionId}/webhooks \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"url": "https://your-server.com/webhook",
"events": ["message.received", "session.status"],
"secret": "your-hmac-secret"
}'
```
> **智能过滤器(可选):** 添加 `filters` 对象,仅在条件匹配(AND)时触发 webhook,例如 `{ "conditions": [{ "field": "sender", "operator": "is", "value": ["1234567890@c.us"] }] }`。
> 字段:`sender` / `recipient` / `body` / `type` / `mentions` / `fromMe` / `hasMedia` / `isGroup`。不带过滤器的 webhook 行为与之前完全一致。完整 schema 请参阅 API 规范。
## 🤖 MCP ServerAI 智能体)
OpenWA 可通过 [Model Context Protocol](https://modelcontextprotocol.io)** so AI agentsClaude、Cursor 等)驱动 WhatsApp。默认**关闭**且为**附加功能** —— 所有 REST 路由保持原样不变。
`MCP_ENABLED=true` 设置为在现有服务器的 **`POST /mcp`** 上挂载无状态 Streamable-HTTP 传输(同一端口,无需额外进程)。它暴露约 39 个精选工具(会话、消息、联系人、基础群组操作、webhook 读取)—— 相比完整 API 是精简面,避免智能体不堪重负,并将破坏性操作排除在智能体路径之外。
```bash
MCP_ENABLED=true npm run start:prod # or set MCP_ENABLED in your .env / compose
```
将 MCP 客户端指向该端点(例如 Claude Code,在项目根目录放置 `.mcp.json`):
```json
{
"mcpServers": {
"openwa": {
"type": "http",
"url": "http://localhost:2785/mcp",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}
```
密钥可通过 `Authorization: Bearer …``X-API-Key: …` 传递。每次工具调用均经过与 REST **相同的 API 密钥认证、角色和按会话作用域**
**安全指南:**
- **为智能体签发专用的最小权限密钥** —— 非管理员、**按会话作用域**的密钥(最多 `OPERATOR` 角色)。明文密钥仅在创建时显示一次;如需轮换,请创建新密钥并删除旧密钥。
- 密钥**不得**携带 IP 允许列表(`allowedIps`)—— MCP 无法获取真实客户端 IP,此类密钥会被拒绝。
- 设置 **`MCP_READONLY=true`** 仅挂载只读工具(无发送/写入)。
- 设置 **`MCP_RATE_LIMIT_MAX`**(默认 `60`)以限制每个 API 密钥在每个时间窗口内的工具调用次数。
- 设置 **`MCP_RATE_LIMIT_WINDOW_MS`**(默认 `60000`)以控制滑动窗口大小(毫秒)。
- **不要在没有前置认证代理的情况下将 `/mcp` 暴露到公网。** 对于自托管、仅本地访问的部署,静态 API 密钥是合适的;公网暴露应使用 OAuth 2.1(尚未实现)。
---
## 🛠 技术栈
| 层级 | 技术 |
| ------------- | ----------------------- |
| **Runtime** | Node.js 22 LTS |
| **Framework** | NestJS 11.x |
| **Language** | TypeScript 5.x |
| **WA Engine** | whatsapp-web.js(默认)/ baileys — 通过 `ENGINE_TYPE` 设置 |
| **Database** | SQLite / PostgreSQL |
| **Cache** | Redis(可选) |
| **Storage** | Local / S3 / MinIO |
| **ORM** | TypeORM |
| **Container** | Docker + Docker Compose |
---
## 📁 项目结构
```
openwa/
├── src/
│ ├── main.ts # Application entry point
│ ├── app.module.ts # Root module
│ ├── config/ # Configuration
│ ├── common/ # Shared utilities
│ │ ├── cache/ # Redis caching
│ │ └── storage/ # File storage (Local/S3)
│ ├── core/ # Core systems
│ │ ├── hooks/ # Plugin hooks
│ │ └── plugins/ # Plugin system
│ ├── engine/ # WhatsApp engine abstraction
│ └── modules/
│ ├── session/ # Session management
│ ├── message/ # Message handling
│ ├── webhook/ # Webhook management
│ ├── group/ # Groups API
│ ├── contact/ # Contacts API
│ ├── auth/ # API key authentication
│ ├── infra/ # Infrastructure management
│ └── health/ # Health checks
├── dashboard/ # React web dashboard
├── docs/ # Documentation
├── docker-compose.yml
├── Dockerfile
└── package.json
```
---
## 📚 文档
完整文档位于 `docs/` 文件夹:
| 文档 | 说明 |
| ------------------------------------------------------- | ---------------------------- |
| [Project Overview](./docs/01-project-overview.md) | 简介与目标 |
| [Requirements](./docs/02-requirements-specification.md) | 功能规格说明 |
| [Architecture](./docs/03-system-architecture.md) | 系统设计 |
| [Security](./docs/04-security-design.md) | 安全实现 |
| [Database](./docs/05-database-design.md) | 数据模型与迁移 |
| [API Spec](./docs/06-api-specification.md) | 完整 API 参考 |
| [Development](./docs/08-development-guidelines.md) | 编码规范 |
| [Migration Guide](./docs/14-migration-guide.md) | 数据库与存储迁移 |
---
## 🤝 贡献
欢迎贡献!入门步骤如下:
1. **Fork** 本仓库
2. **创建** 你的功能分支(`git checkout -b feature/amazing-feature`
3. **提交** 你的更改(`git commit -m 'Add amazing feature'`
4. **推送** 到该分支(`git push origin feature/amazing-feature`
5. **打开** Pull Request
请阅读我们的 [Development Guidelines](./docs/08-development-guidelines.md) 了解编码规范与最佳实践。
---
## 📄 许可证
本项目采用 **MIT License** 许可 —— 可免费用于个人和商业用途。
详见 [LICENSE](./LICENSE)。
---
<div align="center">
**OpenWA** – 免费、开源的 WhatsApp API 网关
[📖 文档](./docs/README.md) · [🔌 API 文档](http://localhost:2785/api/docs) · [🐛 报告 Bug](https://github.com/rmyndharis/OpenWA/issues) · [💡 功能建议](https://github.com/rmyndharis/OpenWA/issues)
<br/>
<sub>由 <a href="https://github.com/rmyndharis">Yudhi Armyndharis</a> 与 OpenWA 社区用 ❤️ 制作</sub>
</div>