add: 增加配置说明
This commit is contained in:
@@ -0,0 +1,304 @@
|
||||
# Node.js 4G SMS Gateway
|
||||
|
||||
基于Node.js的4G短信网关,通过串口与4G模块通信,接收短信并转发到多种推送渠道。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- ✅ 4G模块AT指令交互
|
||||
- ✅ 自动接收短信(PDU模式)
|
||||
- ✅ 长短信自动合并
|
||||
- ✅ 多通道推送(邮件/钉钉/飞书/Telegram等)
|
||||
- ✅ 短信发送功能
|
||||
- ✅ RESTful API接口
|
||||
- ✅ Web管理界面
|
||||
|
||||
## 环境要求
|
||||
|
||||
- Node.js >= 18.x
|
||||
- 4G模块通过USB转串口连接到服务器
|
||||
- 支持的4G模块:ML307R-DC、SIM7600等AT指令兼容模块
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
## 配置
|
||||
|
||||
复制配置模板:
|
||||
```bash
|
||||
cp config.example.json config.json
|
||||
```
|
||||
|
||||
`config.json` 必须存在,否则程序会直接退出。最小可运行配置如下:
|
||||
|
||||
```json
|
||||
{
|
||||
"serial": {
|
||||
"path": "/dev/ttyUSB0",
|
||||
"baudRate": 115200,
|
||||
"autoDetect": true,
|
||||
"probeTimeout": 1200
|
||||
},
|
||||
"api": {
|
||||
"port": 3000,
|
||||
"webToken": "change-this-token"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
完整配置可参考 `config.example.json`。主要配置项如下:
|
||||
|
||||
| 配置项 | 是否必填 | 说明 |
|
||||
|--------|----------|------|
|
||||
| `serial.path` | 是 | 串口路径;Linux 常用 `/dev/ttyUSB0`,Windows 使用 `COM3` 等。`autoDetect=true` 时作为优先探测项,`autoDetect=false` 时作为实际串口。 |
|
||||
| `serial.baudRate` | 是 | 串口波特率,通常为 `115200`。 |
|
||||
| `serial.autoDetect` | 否 | 是否自动探测可响应 `AT` 的串口,默认按非 `false` 处理。 |
|
||||
| `serial.probeTimeout` | 否 | 自动探测单个串口的超时时间,单位毫秒,默认 `1200`。 |
|
||||
| `api.port` | 是 | API 和 Web 管理台监听端口。 |
|
||||
| `api.webToken` | 是 | 唯一鉴权凭据;已取消 `admin/admin123` Basic Auth。 |
|
||||
| `mobileData.cid` | 否 | 移动数据 PDP CID,默认 `1`;有效范围 `1-15`,不要使用 `8`。 |
|
||||
| `simCards` | 否 | SIM 卡显示手机号,`slot=0` 是 SIM1,`slot=1` 是 SIM2。 |
|
||||
| `smtp` | 否 | 邮件通知配置;填写 `smtp.server` 后启用。 |
|
||||
| `inbox` | 否 | Web 收件箱持久化和双卡显示策略。 |
|
||||
| `pushChannels` | 否 | 推送通道列表;通道开启后才要求目标字段。 |
|
||||
|
||||
`api.webToken` 可以通过以下方式传入:
|
||||
|
||||
- `Authorization: Bearer <token>`
|
||||
- `X-Web-Token: <token>`
|
||||
- `?token=<token>`
|
||||
- Web 管理台 token 登录页
|
||||
|
||||
### 完整配置示例
|
||||
|
||||
```json
|
||||
{
|
||||
"serial": {
|
||||
"path": "/dev/ttyUSB0",
|
||||
"baudRate": 115200,
|
||||
"autoDetect": true,
|
||||
"probeTimeout": 1200
|
||||
},
|
||||
"mobileData": {
|
||||
"cid": 1
|
||||
},
|
||||
"simCards": [
|
||||
{ "slot": 0, "phoneNumber": "+8613800138000" },
|
||||
{ "slot": 1, "phoneNumber": "+447700900000" }
|
||||
],
|
||||
"smtp": {
|
||||
"server": "smtp.qq.com",
|
||||
"port": 465,
|
||||
"user": "your@qq.com",
|
||||
"pass": "your_auth_code",
|
||||
"sendTo": "recipient@example.com"
|
||||
},
|
||||
"inbox": {
|
||||
"maxReceivedMessages": 200,
|
||||
"receivedMessagesFile": "data/received-messages.json",
|
||||
"partitionBySim": true,
|
||||
"allowAllSimMessages": false,
|
||||
"dualSimDefaultScope": "all"
|
||||
},
|
||||
"pushChannels": [
|
||||
{
|
||||
"enabled": true,
|
||||
"type": "dingtalk",
|
||||
"name": "钉钉通知",
|
||||
"url": "https://oapi.dingtalk.com/robot/send?access_token=xxx",
|
||||
"secret": "SECxxx"
|
||||
}
|
||||
],
|
||||
"api": {
|
||||
"port": 3000,
|
||||
"webToken": "change-this-token"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 可选项细节
|
||||
|
||||
- `smtp`:不需要邮件时可以删除整个对象,或清空 `server`。启用邮件时需要正确填写 `server`、`port`、`user`、`pass`、`sendTo`。
|
||||
- `inbox.maxReceivedMessages`:默认 `200`,最大按 `5000` 处理。
|
||||
- `inbox.receivedMessagesFile`:默认 `data/received-messages.json`,相对路径会基于项目根目录解析。
|
||||
- `inbox.partitionBySim`:默认 `true`,按当前 SIM 隔离历史短信。
|
||||
- `inbox.allowAllSimMessages`:默认 `false`,控制是否允许显式查询全部 SIM 历史。
|
||||
- `inbox.dualSimDefaultScope`:可选 `all` 或 `current`;`current` 表示双卡时默认只看当前 SIM。
|
||||
- `simCards`:只影响管理台显示,不影响短信收发。代码也兼容旧字段名 `simSlots`、`sims`、`sim`。
|
||||
|
||||
## 运行
|
||||
|
||||
### 开发模式
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### 生产模式
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
### 使用PM2(推荐)
|
||||
```bash
|
||||
pm2 start ecosystem.config.js
|
||||
pm2 save
|
||||
pm2 startup
|
||||
```
|
||||
|
||||
## API接口
|
||||
|
||||
### 查询状态
|
||||
```bash
|
||||
GET /api/status
|
||||
```
|
||||
|
||||
### 发送短信
|
||||
```bash
|
||||
POST /api/sms/send
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"phone": "13800138000",
|
||||
"message": "测试短信"
|
||||
}
|
||||
```
|
||||
|
||||
### 查询收到的短信
|
||||
```bash
|
||||
GET /api/sms/received?limit=50
|
||||
```
|
||||
|
||||
双卡双待模式下,默认返回全部 SIM 历史;显式传 `scope=current` 时才按当前卡槽过滤。短信记录会保留 `simSlot`、`simLabel` 与 `simSource`,用于判断收件卡槽。
|
||||
也可以显式按卡槽查询:
|
||||
|
||||
```bash
|
||||
GET /api/sms/received?limit=50&simSlot=0 # SIM1
|
||||
GET /api/sms/received?limit=50&simSlot=1 # SIM2
|
||||
```
|
||||
|
||||
直出模式下,新短信主要通过模组 `+CMT` URC 进入收件箱;如果 URC 未携带卡槽信息,会显示为未知 SIM。
|
||||
|
||||
### 查询信号强度
|
||||
```bash
|
||||
GET /api/modem/signal
|
||||
```
|
||||
|
||||
### 查询模组信息
|
||||
```bash
|
||||
GET /api/modem/info
|
||||
```
|
||||
|
||||
### 查询与切换SIM
|
||||
```bash
|
||||
GET /api/modem/sim
|
||||
POST /api/modem/sim/switch
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"slot": 1
|
||||
}
|
||||
```
|
||||
|
||||
当模组返回 `AT+DUALSIM?`、`AT+SWITCHSIM?` 与 `AT+BINDSIM?` 能力时,管理台会显示 SIM1/SIM2。短信接收使用 `CNMI` 直出模式,不为了接收短信切换 `SWITCHSIM`。如果模组上报的 URC 未携带卡槽信息,新短信会记录为未知 SIM。
|
||||
|
||||
管理台切卡会同时设置 `AT+SWITCHSIM` 与 `AT+BINDSIM`,随后恢复短信直出配置。发送短信前会提示当前使用的 SIM。
|
||||
|
||||
如果希望管理台显示手机号,可在 `config.json` 中配置:
|
||||
|
||||
```json
|
||||
{
|
||||
"simCards": [
|
||||
{ "slot": 0, "phoneNumber": "+8613800138000" },
|
||||
{ "slot": 1, "phoneNumber": "+447700900000" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 发送AT命令
|
||||
```bash
|
||||
POST /api/modem/at
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"command": "AT+CSQ"
|
||||
}
|
||||
```
|
||||
|
||||
### 获取日志
|
||||
```bash
|
||||
GET /api/logs
|
||||
```
|
||||
|
||||
所有API均需要有效 token。可以通过 `Authorization: Bearer <token>`、`X-Web-Token` 请求头或 `token` 查询参数传入。
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
.
|
||||
├── src/
|
||||
│ ├── index.js # 入口文件
|
||||
│ ├── modem.js # 4G模块通信
|
||||
│ ├── sms.js # 短信处理
|
||||
│ ├── push.js # 推送通道
|
||||
│ ├── concat.js # 长短信合并
|
||||
│ ├── api.js # REST API
|
||||
│ └── logger.js # 日志系统
|
||||
├── config.json # 配置文件
|
||||
├── package.json
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 推送通道类型
|
||||
|
||||
| 类型 | type值 | 配置项 |
|
||||
|------|--------|--------|
|
||||
| 钉钉机器人 | `dingtalk` | url, secret(可选) |
|
||||
| 飞书机器人 | `feishu` | url, secret(可选) |
|
||||
| Telegram Bot | `telegram` | url(bot token), key1(chat_id) |
|
||||
| PushPlus | `pushplus` | key1(token) |
|
||||
| Server酱 | `serverchan` | key1(sendkey) |
|
||||
| Bark | `bark` | url(bark服务器) |
|
||||
| POST JSON | `post_json` | url |
|
||||
| GET请求 | `get` | url |
|
||||
| 自定义模板 | `custom` | url, customBody |
|
||||
|
||||
`pushChannels` 中 `enabled: false` 的通道可以保留空字段;`enabled: true` 时必须配置对应目标:
|
||||
|
||||
- `post_json`、`bark`、`get`、`dingtalk`、`custom`、`feishu`:必须有 `url`。
|
||||
- `telegram`:`url` 填 Bot Token,`key1` 填 Chat ID。
|
||||
- `pushplus`:`key1` 填 PushPlus Token。
|
||||
- `serverchan`:`key1` 填 Server酱 SendKey。
|
||||
- `custom`:`customBody` 如果填写,必须是合法 JSON 字符串,支持 `{sender}`、`{message}`、`{timestamp}` 占位符。
|
||||
|
||||
## 长短信处理
|
||||
|
||||
- 自动检测长短信(分段数 > 1)
|
||||
- 使用参考号和发送者号码标识同一条长短信
|
||||
- 收齐所有分段后自动合并
|
||||
- 30秒超时保护(未收齐也转发)
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 串口打不开
|
||||
```bash
|
||||
# Linux检查串口设备
|
||||
ls -l /dev/ttyUSB*
|
||||
# 添加用户到dialout组
|
||||
sudo usermod -a -G dialout $USER
|
||||
```
|
||||
|
||||
### 模块不响应
|
||||
- 检查串口路径和波特率
|
||||
- 检查USB连接
|
||||
- 检查SIM卡是否插好
|
||||
|
||||
### 收不到短信
|
||||
- 检查AT+CEREG?网络注册状态
|
||||
- 检查AT+CNMI配置是否正确
|
||||
- 检查SIM卡余额和服务状态
|
||||
|
||||
## 许可证
|
||||
|
||||
MIT
|
||||
Reference in New Issue
Block a user