UNPKG

redis-auth-baileys

Version:

A Redis-based authentication state management system for Baileys, similar to Baileys' useMultiFileAuth, providing scalable and production-ready session storage for WhatsApp bots.

116 lines (102 loc) 3.09 kB
const { Mutex } = require('async-mutex'); const { createClient } = require('redis'); const { initAuthCreds } = require('baileys/lib/Utils/auth-utils'); const { BufferJSON } = require('baileys/lib/Utils/generics'); /** * Stores the full authentication state in Redis. * This is more suitable for production-level use compared to file storage. */ const useRedisAuthState = async (redisConfig, redisPrefix) => { // const client = createClient(redisConfig); const redisURI = `redis://:${redisConfig.password}@${redisConfig.host}:${redisConfig.port}`; const client = createClient({ url: redisURI }); client.on('error', (err) => { console.error('Redis error:', err); }); await client.connect(); // We need to lock data due to the fact that we are using async functions to access Redis const fileLocks = new Map(); // Get or create a mutex for a specific Redis key const getRedisLock = (key) => { let mutex = fileLocks.get(key); if (!mutex) { mutex = new Mutex(); fileLocks.set(key, mutex); } return mutex; }; // Menambahkan prefix pada kunci const prefixKey = (key) => `${redisPrefix}:${key}`; const readData = async (key) => { try { const mutex = getRedisLock(key); return await mutex.acquire().then(async (release) => { try { const data = await client.get(prefixKey(key)); // Menambahkan prefix pada kunci return data ? JSON.parse(data, BufferJSON.reviver) : null; } finally { release(); } }); } catch (error) { return null; } }; const writeData = async (data, key) => { const mutex = getRedisLock(key); return mutex.acquire().then(async (release) => { try { await client.set(prefixKey(key), JSON.stringify(data, BufferJSON.replacer)); // Menambahkan prefix pada kunci } finally { release(); } }); }; const removeData = async (key) => { const mutex = getRedisLock(key); return mutex.acquire().then(async (release) => { try { await client.del(prefixKey(key)); // Menambahkan prefix pada kunci } finally { release(); } }); }; const creds = await readData('creds') || initAuthCreds(); const state = { creds, keys: { get: async (type, ids) => { const data = {}; await Promise.all( ids.map(async (id) => { const value = await readData(`${type}-${id}`); data[id] = value; }) ); return data; }, set: async (data) => { const tasks = []; for (const category in data) { for (const id in data[category]) { const value = data[category][id]; const key = `${category}-${id}`; tasks.push(value ? writeData(value, key) : removeData(key)); } } await Promise.all(tasks); } } }; const saveCreds = async () => { await writeData(creds, 'creds'); }; return { state, saveCreds }; }; module.exports = { useRedisAuthState };