如何让运行中的Node.js脚本检测目录新增文件并触发WhatsApp消息?
解决方案
一、推荐方案:Node.js持续监听目录+会话持久化
这个方案无需反复重启Node.js,WhatsApp保持在线状态,直接监听图片目录的新增文件并自动发送。
1. 实现WhatsApp会话持久化(避免重复扫码)
修改客户端初始化逻辑,加入会话存储功能,将登录状态保存到本地文件,下次启动时自动加载:
const { Client, MessageMedia } = require('whatsapp-web.js'); const fs = require('fs'); const path = require('path'); const chokidar = require('chokidar'); // 更可靠的跨平台目录监听库,先执行:npm install chokidar // 会话存储文件路径 const SESSION_FILE_PATH = './session.json'; let sessionData; // 读取已保存的会话数据 if (fs.existsSync(SESSION_FILE_PATH)) { sessionData = require(SESSION_FILE_PATH); } // 初始化客户端,传入会话数据 const client = new Client({ session: sessionData }); // 监听会话更新,实时保存到文件 client.on('authenticated', (session) => { sessionData = session; fs.writeFile(SESSION_FILE_PATH, JSON.stringify(session), (err) => { if (err) console.error('保存会话失败:', err); }); }); // 会话失效时删除旧文件,下次启动重新登录 client.on('auth_failure', () => { console.log('会话已失效,请重新扫码'); if (fs.existsSync(SESSION_FILE_PATH)) { fs.unlinkSync(SESSION_FILE_PATH); } });
2. 监听图片目录+自动发送消息
在客户端就绪后,先获取一次目标聊天对象并缓存,再启动目录监听:
let targetChat; // 缓存目标聊天,避免重复查询 client.on("ready", async () => { console.log('客户端已就绪!'); // 获取目标聊天,仅执行一次 const chats = await client.getChats(); targetChat = chats.find((chat) => chat.name === '<Chat Name>'); if (!targetChat) { console.error('未找到目标聊天,请检查群名是否正确'); return; } // 监听指定图片目录(替换为你的实际图片保存路径) const watcher = chokidar.watch('./cat_images', { ignored: /^\./, // 忽略隐藏文件 persistent: true, ignoreInitial: true // 忽略目录中已存在的文件,只处理新增的 }); // 监听文件新增事件 watcher.on('add', async (filePath) => { // 仅处理图片格式文件(可按需扩展后缀) const ext = path.extname(filePath).toLowerCase(); if (['.jpg', '.jpeg', '.png', '.gif'].includes(ext)) { try { const media = MessageMedia.fromFilePath(filePath); await targetChat.sendMessage(media, {caption: "beep boop cat detected"}); console.log(`已发送图片:${filePath}`); } catch (err) { console.error('发送图片失败:', err); } } }); console.log('已开始监听图片目录...'); }); client.initialize();
3. 安装依赖
执行以下命令安装所需依赖库:
npm install whatsapp-web.js chokidar
二、备选方案:Python触发Node.js(保持WhatsApp在线)
如果坚持用Python触发发送操作,不要重启Node.js,而是将Node.js做成HTTP服务,Python保存图片后调用服务接口触发发送:
1. Node.js端(HTTP服务+会话持久化)
const { Client, MessageMedia } = require('whatsapp-web.js'); const fs = require('fs'); const express = require('express'); // 执行:npm install express const app = express(); const PORT = 3000; // 会话持久化逻辑和上方一致 const SESSION_FILE_PATH = './session.json'; let sessionData; if (fs.existsSync(SESSION_FILE_PATH)) { sessionData = require(SESSION_FILE_PATH); } const client = new Client({ session: sessionData }); let targetChat; client.on('authenticated', (session) => { sessionData = session; fs.writeFile(SESSION_FILE_PATH, JSON.stringify(session), (err) => { if (err) console.error('保存会话失败:', err); }); }); client.on('ready', async () => { console.log('WhatsApp客户端已就绪'); const chats = await client.getChats(); targetChat = chats.find(chat => chat.name === '<Chat Name>'); if (!targetChat) { console.error('未找到目标聊天'); } }); // 定义接收触发请求的接口 app.get('/send-cat', async (req, res) => { if (!targetChat) { return res.status(500).send('目标聊天未初始化'); } const imagePath = req.query.path; if (!imagePath) { return res.status(400).send('缺少图片路径参数'); } try { const media = MessageMedia.fromFilePath(imagePath); await targetChat.sendMessage(media, {caption: "beep boop cat detected"}); res.send('图片发送成功'); } catch (err) { console.error('发送失败:', err); res.status(500).send('发送失败'); } }); // 启动HTTP服务 app.listen(PORT, () => { console.log(`服务已启动,端口:${PORT}`); }); client.initialize();
2. Python端调用接口
在Python保存图片后,发送HTTP请求触发发送:
import requests # 保存图片后执行以下代码 image_path = "./output.jpg" response = requests.get(f"http://localhost:3000/send-cat?path={image_path}") print(response.text)
注意事项
- 可用
pm2等工具守护Node.js进程,避免意外退出导致服务中断 - 确保图片目录路径正确,Node.js进程有读取该目录的权限
- 不要随意删除
session.json文件,除非需要重新登录WhatsApp
内容的提问来源于stack exchange,提问作者MergeMonster
相关产品推荐
相关产品推荐

