跳转到内容

通知设置

通知设置

本节介绍如何设置 Node-RED 通知系统,当 ESP32-CAM 检测到运动并拍照后,自动通过 Telegram Bot 和 Email 发送通知。学习完成后,您将能够:

  • 创建和配置 Telegram Bot
  • 在 Node-RED 中集成 Telegram 通知节点
  • 设置图片+文本的推送通知
  • 配置 Email 通知作为备用通道
┌────────────────────────────────────────────────────────────┐
│ 远程巡检通知系统 │
├────────────────────────────────────────────────────────────┤
│ │
│ [ESP32-CAM 检测到运动 → 拍照] │
│ │ │
│ ▼ │
│ [Node-RED] │
│ │ │
│ ├──→ [保存图片到服务器] │
│ │ │
│ ├──→ [Telegram Bot] │
│ │ ├──→ 发送文本消息: "检测到运动!" │
│ │ ├──→ 延迟 1 秒 │
│ │ └──→ 发送图片文件 │
│ │ │
│ └──→ [Email 通知] │
│ ├──→ 发送 HTML 格式邮件(包含嵌入式图片) │
│ └──→ 抄送管理员 │
│ │
└────────────────────────────────────────────────────────────┘
1. 打开 Telegram App
2. 搜索 @BotFather → 点击 Start
3. 发送: /newbot
4. 输入 Bot 名称: "Factory Monitor Bot" (可自定义)
5. 输入 Bot 用户名: "factory_monitor_bot" (必须以 bot 结尾)
6. BotFather 返回 API Token:
=> 1234567890:ABCDefghIJKlmnopQRStuVWXyz1234567890
7. 可选: 自定义 Bot 头像和描述
/setuserpic → 上传 Bot 头像
/setdescription → 设置 Bot 描述
8. 保存 Token,后续 Node-RED 需要
1. 搜索你刚创建的 Bot 用户名 → 点击 Start
2. Node-RED 将接收到包含 chat ID 的消息
3. 发送任意消息到 Bot 以获取聊天 ID
Terminal window
# 通过 Palette 管理
# Manage Palette → Install → "node-red-contrib-telegrambot"
# 或命令行
docker exec -it nodered npm install node-red-contrib-telegrambot

Step 3: Configure Telegram Bot in Node-RED

Section titled “Step 3: Configure Telegram Bot in Node-RED”
[Telegram Receiver] ──→ [Debug: 查看消息]
[Function: 构建通知] ──→ [Telegram Sender]

Telegram Bot 配置节点:

参数
NameFactory Monitor Bot
Bot Token1234567890:ABCDefghIJKlmnopQRStuVWXyz1234567890
TypeBot

部署后向 Bot 发送任意消息,Telegram Receiver 节点将收到:

{
"payload": {
"chatId": "987654321",
"type": "message",
"content": "/start",
"from": {
"id": 12345,
"first_name": "User"
}
}
}

记录 Chat ID: 记录下 chatId 值(例如 987654321),后续发送通知时使用。

[MQTT In: esp32cam/photo]
├──→ [Write File: 保存图片到 /data/esp32cam/]
└──→ [Function: 发送 Telegram 文本]
│ │
│ └──→ [Telegram Sender: 文本消息]
├──→ [Delay: 1 秒]
└──→ [Function: 发送 Telegram 图片]
└──→ [Telegram Sender: 图片]
// Function: 构建 Telegram 文本消息
// 当收到新图片时,发送通知消息
// 从 Flow Context 获取聊天 ID
var chatId = flow.get("telegramChatId") || "987654321"; // 替换为实际 Chat ID
// 获取图片元数据
var meta = flow.get("lastPhotoMeta") || {};
var message = {
payload: {
chatId: chatId,
type: "message",
content: "⚠️ *远程巡检告警*\n\n" +
"📸 ESP32-CAM 检测到运动并已拍照\n" +
"🕐 时间: " + new Date().toLocaleString() + "\n" +
"📏 图片大小: " + (meta.size || "未知") + " 字节\n" +
"🔢 唤醒次数: " + (meta.boot || "-") + "\n\n" +
"请在 Node-RED Dashboard 查看完整画面。",
parse_mode: "Markdown" // Markdown 格式
}
};
return message;
// Function: 发送已保存的图片
// 从服务器文件系统读取并发送
var chatId = flow.get("telegramChatId") || "987654321";
var fs = require('fs');
var path = "/data/esp32cam/latest.jpg";
// 方式 1: 发送服务器上的文件
try {
if (fs.existsSync(path)) {
var photo = fs.readFileSync(path);
var message = {
payload: {
chatId: chatId,
type: "photo",
content: photo.toString('base64'), // Base64 编码的图片数据
filename: "surveillance_" + Date.now() + ".jpg"
}
};
return message;
}
} catch (e) {
node.error("File read error: " + e.message);
}
return null;
参数
BotFactory Monitor Bot (选择已配置的 Bot)
Typemsg.payload (由 Function 节点动态指定)
Name发送通知

Telegram 对频繁发送消息有限制,添加延迟节点:

[Function: 文本消息] ──→ [Delay: 1 秒] ──→ [Telegram Sender: 文本]
[Function: 图片消息] ──→ [Delay: 2 秒] ──→ [Telegram Sender: 图片]

Delay 节点配置:

参数
ActionDelay each message
Delay1-2 秒
Rate1 message per 1 second

Step 6: Email Notification (Alternative Channel)

Section titled “Step 6: Email Notification (Alternative Channel)”
Terminal window
# 通过 Palette 安装
npm install node-red-node-email

使用 Node-RED 的 Email 节点发送图片通知:

[MQTT In: esp32cam/photo]
└──→ [Function: 构建邮件]
└──→ [Email: 发送]

Email 节点配置:

参数
Toadmin@factory.com
Fromno-reply@factory-monitor.local
Serversmtp.gmail.com (或其他 SMTP)
Port465 (SSL) 或 587 (TLS)
SecuritySSL/TLS
Authentication✅ 启用
UserIdyour-email@gmail.com
Password应用专用密码
// Function: 构建带图片的 HTML 邮件
// msg.payload 为二进制图片数据
// 图片编码为 Base64 嵌入 HTML
var base64Image = msg.payload.toString('base64');
msg.payload = "";
msg.topic = "📸 远程巡检告警 - " + new Date().toLocaleString();
msg.envelope = {
to: "admin@factory.com",
from: "no-reply@factory-monitor.local"
};
msg.payload = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body { font-family: Arial, sans-serif; }
.header {
background: #dc3545;
color: white;
padding: 15px;
text-align: center;
}
.content { padding: 20px; }
img {
max-width: 100%;
border: 1px solid #ddd;
border-radius: 8px;
}
.footer {
font-size: 12px;
color: #666;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="header">
<h2>⚠️ 远程巡检告警通知</h2>
</div>
<div class="content">
<p><strong>检测时间:</strong> ${new Date().toLocaleString()}</p>
<p><strong>设备:</strong> ESP32-CAM (Factory Area A)</p>
<p><strong>事件:</strong> PIR 运动传感器触发</p>
<hr>
<h3>📷 现场照片:</h3>
<img src="cid:photo" alt="现场照片">
<hr>
<p><a href="http://nodered.local:1880/ui">👉 查看完整 Dashboard</a></p>
</div>
<div class="footer">
<p>此邮件由工厂远程巡检系统自动发送</p>
</div>
</body>
</html>`;
// 添加内联图片附件
msg.payloadType = 'html';
msg.attachments = [
{
filename: 'photo.jpg',
data: base64Image,
encoding: 'base64',
cid: 'photo' // Content-ID,用于 HTML 中引用
}
];
return msg;
Terminal window
# 1. 测试 Telegram Bot
# 向 Bot 发送 /start,确认 Node-RED 接收
# 输出: chatId: 987654321
# 2. 触发拍照并验证通知
mosquitto_pub -t "esp32cam/command" -m "take_photo"
# 3. 验证 Telegram 是否收到
# 手机端应收到:
# ⚠️ 远程巡检告警
# 📸 ESP32-CAM 检测到运动并已拍照
# 🕐 时间: 5/18/2026, 14:30:25
# 1秒后收到照片
# 4. 验证 Email 是否收到
# 检查管理员邮箱

Q1: Telegram 通知能否推送到群组?

Section titled “Q1: Telegram 通知能否推送到群组?”

可以。创建群组后将 Bot 添加到群组,然后在群组中发送 /start,获取群组的 Chat ID,使用该 ID 发送消息。

在 Node-RED 中添加时间判断:

// Function: 时间过滤
var hour = new Date().getHours();
if (hour >= 22 || hour < 7) {
// 夜间: 静默处理,仅记录不通知
msg.payload = null;
return msg;
}
// 白天: 正常通知
return msg;
// Function: 群发通知
var recipients = [
"987654321", // 管理员
"876543210", // 值班工程师
"-123456789" // 群组 (负数表示群组)
];
// 创建消息队列
var messages = [];
recipients.forEach(function(chatId) {
messages.push({
payload: {
chatId: chatId,
type: "message",
content: "⚠️ 远程巡检告警..."
}
});
});
// 发送第一条消息,后续通过 Node-RED Loop
return [messages[0]];

推荐做法:

  • Telegram 文本和图片分开发送,中间加 1-2 秒延迟
  • 使用 Markdown 格式化消息增强可读性
  • 图片保存到服务器后再发送(而非直接转发 MQTT 缓冲)
  • 配置备用通知通道(Telegram + Email)
  • 记录 Chat ID 到 Flow Context,避免硬编码

避免做法:

  • 文本和图片合并为一条消息发送
  • 频繁发送通知(建议同一事件 5 分钟内不重复推送)
  • 未验证 Chat ID 是否正确就发送消息
  • 将 Bot Token 硬编码在 Flow 中暴露
  1. Telegram Bot 通过 BotFather 创建,获取 API Token
  2. node-red-contrib-telegrambot 提供 Receiver/Sender 节点
  3. 文本+图片分开发送,中间加 1-2 秒延迟
  4. Email 通知作为备用通道,支持 HTML 格式和嵌入式图片
  5. Chat ID 标识接收者,支持个人和群组推送