钉钉群机器人消息推送服务。提供 HTTP API 将消息推送到钉钉群,附带服务器健康监控脚本。
- Node.js >= 16(建议 >= 18 LTS)
- Linux(systemd 部署)或 macOS(开发调试)
# 1. 配置环境变量
export DINGTALK_WEBHOOK_URL="https://oapi.dingtalk.com/robot/send?access_token=xxx"
export DINGTALK_SECRET="SECxxx" # 未配置加签则不需要
export DINGTALK_API_TOKEN="" # 可选,API 鉴权 token,设置后调用需带 Authorization 头
export DINGTALK_ACCESS_LOG="" # 可选,请求日志文件路径,不设置则不写文件
export PORT=3000 # 可选,默认 3000
# 2. 启动
npm start# text 消息
curl -X POST http://localhost:3000/api/v1/push \
-H "Content-Type: application/json" \
-d '{"msgtype":"text","content":"hello"}'
# 如果配置了 DINGTALK_API_TOKEN,需携带 Authorization 头
curl -X POST http://localhost:3000/api/v1/push \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"msgtype":"text","content":"hello"}'
# markdown 消息
curl -X POST http://localhost:3000/api/v1/push \
-H "Content-Type: application/json" \
-d '{"msgtype":"markdown","title":"标题","content":"# hello\n**bold**"}'
# @指定成员
curl -X POST http://localhost:3000/api/v1/push \
-H "Content-Type: application/json" \
-d '{"msgtype":"text","content":"hello","atMobiles":["138xxxx"],"isAtAll":false}'
# 标记来源主机(多服务器共用推送服务时区分来源)
curl -X POST http://localhost:3000/api/v1/push \
-H "Content-Type: application/json" \
-d '{"msgtype":"markdown","title":"标题","content":"## 备份完成","hostname":"server-b"}'推送消息到钉钉群。
鉴权
如果配置了 DINGTALK_API_TOKEN,请求需携带 Authorization: Bearer <token> 请求头,否则返回 401。
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| msgtype | string | 是 | "text" 或 "markdown" |
| content | string | 是 | 消息内容 |
| title | string | 否 | markdown 标题,msgtype 为 markdown 时生效 |
| atMobiles | string[] | 否 | @成员的手机号列表 |
| isAtAll | bool | 否 | 是否 @所有人 |
| hostname | string | 否 | 来源主机标识,text 消息前加 [hostname],markdown 顶部加 **来源**: hostname |
响应
{ "ok": true }
{ "ok": false, "errcode": 300005, "errmsg": "token is not exist" }健康检查。
{ "status": "ok" }scp -r src package.json scripts deploy .env.example user@server:/opt/dingtalk-notice/cd /opt/dingtalk-notice
cp .env.example .env
vi .env # 填入 DINGTALK_WEBHOOK_URL、DINGTALK_SECRET、DINGTALK_API_TOKEN(可选)sudo bash scripts/install.sh脚本支持两种部署模式:
- 模式 1 — 安装钉钉推送服务:环境检查 → 安装 systemd 服务 → 启动,本机作为推送服务器
- 模式 2 — 外接推送服务:交互式输入远程 IP/端口/Token/主机名,只装监控脚本,连接已有推送服务器。此模式不依赖 Node.js,只需 bash + curl
如果不想用 install.sh,也可以分步操作:
sudo bash scripts/check.sh # 先检查环境
sudo cp deploy/dingtalk-notice.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now dingtalk-notice服务配置了 Restart=always,进程崩溃后 5 秒自动重启,开机自启。
sudo bash /opt/dingtalk-notice/scripts/uninstall.sh停止并移除 systemd 服务,保留项目目录和 Node.js。cron 定时任务由用户安装时手动设定,卸载后需自行清理:
rm -rf /opt/dingtalk-notice # 删除项目文件
crontab -e # 移除 monitor.sh 的 cron 行scripts/monitor.sh 每分钟检查服务状态和系统资源,异常时自动推送告警到钉钉。可独立部署在任意服务器上,通过 PUSH_ENDPOINT 指向中央推送服务,区分 HOSTNAME 标识来源。
编辑 scripts/monitor.conf:
# 检查 systemd 服务是否运行
CHECK_SERVICES="nginx.service docker.service"
# 检查端口是否监听
CHECK_PORTS="80 443 8080"
# 内存阈值(超过则告警)
MEMORY_THRESHOLD=80
# 磁盘阈值(挂载点:百分比)
DISK_THRESHOLDS="/:80 /data:90"
# 告警消息中显示的主机名(为空则自动获取 hostname)
HOSTNAME=""
# 推送地址
PUSH_ENDPOINT="http://localhost:3000/api/v1/push"
# API 鉴权 Token(在项目 .env 中配置 DINGTALK_API_TOKEN,此处可覆盖)
# 日志文件路径(为空则不写日志)
LOG_FILE="/opt/dingtalk-notice/logs/monitor.log"修改配置后无需重启任何服务,下次 cron 执行自动生效。
crontab -e
# 每分钟执行
* * * * * /bin/bash /opt/dingtalk-notice/scripts/monitor.sh**来源**: prod-server-01
## 服务器告警
**时间**: 2026-07-27 14:30:00
### 服务异常
- nginx.service: 已停止
- 端口 443: 无进程监听
### 资源异常
- 内存: 85% (阈值 80%)
- 磁盘 /data: 92% (阈值 90%)
无异常时静默退出,不发消息。多种异常合并为一条 markdown 消息推送。
配置 LOG_FILE 后,每次执行会写入日志,超过 5000 行自动截断:
[2026-07-27 15:10:27] ===== 开始检查 =====
[2026-07-27 15:10:27] 服务检查: 2/2 正常
[2026-07-27 15:10:27] 资源检查: 2/2 正常
[2026-07-27 15:10:27] 一切正常,退出
benchmark/benchmark.js 测量服务进程真实的 CPU、内存、延迟分布,生成 Chart.js 交互式 HTML 报告和 SVG 图表。
node benchmark/benchmark.js
# → 终端汇总表 + benchmark/benchmark-report.html + 3 张 SVG 图表- Node.js 22, macOS (Apple Silicon), 本地回环
- 并发级别: 1 / 5 / 10 / 20 / 50 / 100,每级别 3 轮取均值
- 通过
ps采样服务进程真实 CPU% 和 RSS 内存
平均延迟
CPU 与内存消耗
延迟百分位分布
基线内存约 58 MB(Node.js 运行时自身)。100 并发下内存仅增长 ~25 MB,CPU < 10%。 延迟主要来自与钉钉 API 的网络往返(本测试使用假 webhook),服务自身开销可忽略。
Dingtalk-Notice/
├── src/
│ ├── index.js # 入口,路由
│ ├── config.js # .env 配置文件加载
│ ├── handler.js # 请求校验、消息组装
│ └── dingtalk.js # 签名计算、HTTP 发送
├── scripts/
│ ├── check.sh # 部署环境检查脚本
│ ├── install.sh # 一键部署脚本
│ ├── uninstall.sh # 卸载脚本
│ ├── monitor.sh # 服务器监控脚本
│ └── monitor.conf # 监控阈值配置
├── benchmark/
│ ├── benchmark.js # 性能基准测试脚本
│ └── svg-chart.js # SVG 图表生成器
├── deploy/
│ └── dingtalk-notice.service # systemd 单元文件
├── package.json
└── .env.example
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
| DINGTALK_WEBHOOK_URL | 是 | - | 钉钉群机器人 Webhook 地址 |
| DINGTALK_SECRET | 否 | - | 加签密钥,机器人配置了加签时必填 |
| DINGTALK_API_TOKEN | 否 | - | API 鉴权 token,设置后请求需带 Authorization: Bearer <token> 头 |
| DINGTALK_ACCESS_LOG | 否 | - | 请求日志文件路径,不设置则不写文件 |
| PORT | 否 | 3000 | 服务监听端口 |
- Node.js 标准库实现,零外部依赖
- 支持钉钉 Webhook 加签(HMAC-SHA256)
- 请求超时 10 秒
- 结构化请求日志(时间戳、IP、方法、路径、状态码、耗时、UA、Body 大小),支持文件写入和 1MB 自动轮转
- 优雅关闭:收到 SIGTERM 后等待现有请求完成再退出,10 秒超时
- systemd 托管,崩溃自动重启,开机自启