whatsapp-web.js在Heroku用LocalAuth无法持久登录问题求助
解决Heroku上whatsapp-web.js的持久登录问题
你的问题核心在于Heroku的临时文件系统特性:LocalAuth默认把会话数据存在应用的本地目录里,但Heroku的dyno每次重启(包括自动休眠唤醒、部署更新)都会重置这个目录,导致之前的登录会话丢失,必须重新扫码。
下面给你两种可行的解决方案:
方案一:用Redis存储会话数据(推荐)
Redis是Heroku官方支持的持久化存储服务,适合存储这类轻量会话数据,也是whatsapp-web.js官方推荐的远程存储方案。
步骤:
- 安装相关依赖:
npm install redis @wppconnect/wa-version
- 修改代码,替换LocalAuth为RemoteAuth并配置Redis连接:
const { Client, RemoteAuth } = require('whatsapp-web.js'); const { createClient } = require('redis'); const { WA_VERSION } = require('@wppconnect/wa-version'); const createSession = function (id, description) { console.log('Creating session: ' + id); // 初始化Redis客户端,Heroku安装Redis插件后会自动注入REDIS_URL环境变量 const redisClient = createClient({ url: process.env.REDIS_URL }); redisClient.on('error', (err) => console.log('Redis连接错误:', err)); redisClient.connect(); const client = new Client({ restartOnAuthFail: true, puppeteer: { headless: true, args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-accelerated-2d-canvas', '--no-first-run', '--no-zygote', '--single-process', '--disable-gpu' ], }, authStrategy: new RemoteAuth({ clientId: id, dataPath: './remote-auth', // 本地临时缓存路径,可选 // 自定义会话数据的读写逻辑,对接Redis store: { async get(key) { return JSON.parse(await redisClient.get(key)); }, async set(key, value) { await redisClient.set(key, JSON.stringify(value)); }, async delete(key) { await redisClient.del(key); }, }, WA_VERSION, }) }); // 监听会话就绪事件 client.on('ready', () => { console.log(`会话${id}已就绪!`); }); client.initialize(); }; const savedSessions = [ {"id":"123456","description":"exapmle1","ready":true}, {"id":"123457","description":"exapmle2","ready":true} ]; savedSessions.forEach(sess => { createSession(sess.id, sess.description); });
- 在Heroku后台配置Redis:
- 进入你的应用「Resources」标签,搜索「Redis」并添加官方的Heroku Redis插件,按提示完成配置即可。
方案二:修改LocalAuth存储路径到持久化存储(不推荐,操作复杂)
如果不想用Redis,可以将LocalAuth的会话数据存到第三方持久存储(比如AWS S3),但需要额外实现文件读写的适配逻辑,维护成本较高。
示例代码(对接AWS S3):
const { Client, LocalAuth } = require('whatsapp-web.js'); const S3FS = require('s3fs'); // 初始化S3文件系统 const s3fs = new S3FS('你的S3桶名称', { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, }); const createSession = function (id, description) { console.log('Creating session: ' + id); const client = new Client({ restartOnAuthFail: true, puppeteer: { /* 保留你的puppeteer配置 */ }, authStrategy: new LocalAuth({ clientId: id, dataPath: `/s3-sessions/${id}`, // 替换LocalAuth默认的文件读写逻辑,指向S3 fs: { readFile: async (path) => s3fs.readFile(path), writeFile: async (path, data) => s3fs.writeFile(path, data), exists: async (path) => s3fs.exists(path), mkdir: async (path) => s3fs.mkdir(path), readdir: async (path) => s3fs.readdir(path), unlink: async (path) => s3fs.unlink(path), } }) }); client.initialize(); };
额外注意事项
- Heroku免费dyno每天会休眠6小时,重启后本地数据必然丢失,所以必须用远程存储方案才能保持登录状态。
- 确认puppeteer的
--single-process参数在Heroku的Linux容器环境下正常运行(该参数在Windows下无效,但Heroku用的是Linux,无需担心)。 - 建议监听
auth_failure事件,及时捕获并处理登录异常。
内容的提问来源于stack exchange,提问作者roiil
相关产品推荐
相关产品推荐

