### Setup Environment Variables Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Copies the example environment file and prompts the user to edit it with Redis credentials. This is required for the example to run. ```bash cp .env.example .env # Edit .env with your Redis credentials ``` -------------------------------- ### Run Example Script Bash Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Execute the example script using npm, pnpm, or bun. This will start the Baileys WhatsApp client with Redis authentication. ```bash npm run example # or # pnpm example # or # bun run example ``` -------------------------------- ### Environment Configuration for Redis Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Example .env file for configuring Redis connection details and session prefix. Ensure these match your Redis setup. ```bash # .env (copy from .env.example) REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD=your_redis_password # optional SESSION_PREFIX=session # unique name per bot instance ``` -------------------------------- ### Example Script Execution Command Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md The command executed by the package managers to run the example script. Ensure tsx is installed if using this method. ```bash tsx example/example.ts ``` -------------------------------- ### Run Example with Redis Auth Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Executes the example implementation of the library with Redis authentication. Supports flags to disable in-memory store or auto-replies. ```bash bun run example # Flags: --no-store (disable in-memory store), --no-reply (disable auto-replies) ``` -------------------------------- ### Install baileys-redis-auth and Baileys Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Install the library and its peer dependency for Baileys. ```bash npm install baileys-redis-auth # peer dependency npm install baileys ``` -------------------------------- ### Run Example without Store and Auto-replies Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Executes the example implementation, disabling both the in-memory store and auto-replies. ```bash bun run example:no-all ``` -------------------------------- ### Running the Example and Interactive Commands Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Instructions for running the Baileys bot example and common interactive commands once connected. This requires Node.js and the 'bun' or 'npm' package manager. ```bash # Run the bundled example cp .env.example .env bun run example # or: npm run example # Interactive commands once connected: # send 6281234567890 Hello World # logout # help # exit ``` -------------------------------- ### Run Example with Custom Flags Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Executes the example implementation with custom flags passed to the underlying Baileys process. Use '--' to separate bun run flags from example flags. ```bash bun run example -- --no-store ``` ```bash bun run example -- --no-reply ``` -------------------------------- ### Install Dependencies Bash Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Install project dependencies using npm, pnpm, or yarn. Ensure you have Node.js and a package manager installed. ```bash npm install # or # pnpm install # or # yarn install ``` -------------------------------- ### Interactive Commands Help Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md List of available interactive commands for the running example script. Use these to control the WhatsApp client. ```bash send - Send a WhatsApp message logout - Logout and clear session help - Show available commands exit - Exit the application ``` -------------------------------- ### Install baileys-redis-auth Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Install the library using npm. Ensure Node.js v18.x or higher is used. ```bash npm install baileys-redis-auth ``` -------------------------------- ### Configure Environment Variables Bash Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Copy the example environment file and edit it with your Redis configuration. This step is crucial for the example to connect to your Redis instance. ```bash cp .env.example .env # Edit .env with your Redis configuration ``` -------------------------------- ### Complete Baileys Logout and Redis Cleanup Example Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/LOGOUT_GUIDE.md A full example demonstrating how to initialize Baileys with Redis auth, handle connection updates, and clear the Redis session upon logout. ```typescript import { deleteKeysWithPattern, useRedisAuthState } from 'baileys-redis-auth' import makeWASocket, {DisconnectReason} from 'baileys' import type {Boom} from '@hapi/boom' async function startWhatsApp() { const sessionPrefix = 'my-session' const {state, saveCreds, redis} = await useRedisAuthState({ host: 'localhost', port: 6379, }, sessionPrefix) const sock = makeWASocket({ auth: state, // ... other options }) // Save credentials on update sock.ev.on('creds.update', saveCreds) // Handle connection updates sock.ev.on('connection.update', async (update) => { const {connection, lastDisconnect} = update if (connection === 'close') { const statusCode = (lastDisconnect?.error as Boom)?.output?.statusCode if (statusCode === DisconnectReason.loggedOut) { // THIS IS CRITICAL: Clear Redis session on logout await deleteKeysWithPattern({ redis, sessionId: sessionPrefix, logger: console.log // Optional: pass logger for debugging }) console.log('✅ Session cleared successfully') } else { // Reconnect on other errors console.log('Reconnecting...') startWhatsApp() } } }) return sock } // Usage const sock = await startWhatsApp() // Later, when user wants to logout: await sock.logout() // This will trigger the cleanup in connection.update handler ``` -------------------------------- ### Manage Multiple Baileys Redis Sessions Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md This example demonstrates how to list both hash-based and key-value based sessions, and then selectively delete specific sessions using `deleteHSetKeys` and `deleteKeysWithPattern`. Ensure you have the necessary functions imported. ```typescript import { listHSetSessions, listSessions, deleteHSetKeys, deleteKeysWithPattern } from 'baileys-redis-auth' import Redis from 'ioredis' const redis = new Redis({ host: 'localhost', port: 6379 }) async function manageAllSessions() { // List all Hash-based sessions const hashSessions = await listHSetSessions({ redis }) console.log('Hash-based sessions:', hashSessions) // List all key-value based sessions const kvSessions = await listSessions({ redis }) console.log('Key-value based sessions:', kvSessions) // Delete a specific Hash session if (hashSessions.includes('old-session')) { await deleteHSetKeys({ redis, sessionId: 'old-session' }) console.log('Deleted old-session') } // Delete a specific key-value session if (kvSessions.includes('inactive-session')) { await deleteKeysWithPattern({ redis, sessionId: 'inactive-session' }) console.log('Deleted inactive-session') } } manageAllSessions().catch(console.error) ``` -------------------------------- ### Complete WhatsApp Bot with Redis Auth Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt This TypeScript code demonstrates a full WhatsApp bot setup using Baileys and Redis for authentication. It handles environment variable loading for Redis connection, QR code generation, connection updates, message upserts, and session cleanup on logout. Ensure Redis is running and environment variables are set. ```typescript import makeWASocket, { DisconnectReason, fetchLatestBaileysVersion, makeCacheableSignalKeyStore, } from 'baileys' import { useRedisAuthState, deleteKeysWithPattern } from 'baileys-redis-auth' import type { Boom } from '@hapi/boom' import dotenv from 'dotenv' import NodeCache from 'node-cache' import qrcodeTerminal from 'qrcode-terminal' dotenv.config() // .env: REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD= SESSION_PREFIX=session const msgRetryCounterCache = new NodeCache() async function startBot() { const redisOptions = { host: process.env.REDIS_HOST || 'localhost', port: Number.parseInt(process.env.REDIS_PORT || '6379', 10), password: process.env.REDIS_PASSWORD, } const sessionId = process.env.SESSION_PREFIX || 'session' const { state, saveCreds, redis } = await useRedisAuthState( redisOptions, sessionId, console.log ) const { version } = await fetchLatestBaileysVersion() const sock = makeWASocket({ version, auth: { creds: state.creds, keys: makeCacheableSignalKeyStore(state.keys, console.log), }, msgRetryCounterCache, printQRInTerminal: false, getMessage: async () => undefined, }) sock.ev.on('creds.update', saveCreds) sock.ev.on('connection.update', async ({ connection, lastDisconnect, qr }) => { if (qr) { console.log('Scan QR code:') qrcodeTerminal.generate(qr, { small: true }) } if (connection === 'open') { console.log('Connected:', sock.user?.name) } if (connection === 'close') { const code = (lastDisconnect?.error as Boom)?.output?.statusCode if (code === DisconnectReason.loggedOut) { await deleteKeysWithPattern({ redis, sessionId, logger: console.log }) console.log('Session cleared — re-run to create a new session') } else { console.log('Reconnecting...') startBot() } } }) sock.ev.on('messages.upsert', async ({ messages, type }) => { if (type === 'notify') { for (const msg of messages) { const text = msg.message?.conversation || msg.message?.extendedTextMessage?.text if (text && !msg.key.fromMe) { console.log(`Message from ${msg.key.remoteJid}: ${text}`) // Echo back await sock.sendMessage(msg.key.remoteJid!, { text: `You said: ${text}` }) } } } }) return sock } startBot().catch(console.error) ``` -------------------------------- ### Cleanup Auth State on Logout (Key-Value Method) Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Ensure proper cleanup of authentication state on logout to prevent orphaned sessions. This example uses the key-value method for Redis operations. ```typescript if (statusCode === DisconnectReason.loggedOut) { // For HSet method: await deleteHSetKeys({redis, key: prefix}); // For key-value method: await deleteKeysWithPattern({redis, pattern: `${prefix}:*`}); } ``` -------------------------------- ### Redis Key-Value State Storage Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Alternative implementation for storing authentication data as separate Redis keys. Uses SET, GET, DEL operations. Compatible with existing systems but creates more keys. ```typescript import { useRedisAuthState } from 'baileys-redis-auth'; // Example usage: const { state, saveCreds, redis } = await useRedisAuthState({ redis: redisClient, prefix: 'session', }); ``` -------------------------------- ### Cleanup Auth State on Logout (HSet Method) Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Ensure proper cleanup of authentication state on logout to prevent orphaned sessions. This example uses the HSet method for Redis operations. ```typescript if (statusCode === DisconnectReason.loggedOut) { // For HSet method: await deleteHSetKeys({redis, key: prefix}); // For key-value method: // await deleteKeysWithPattern({redis, pattern: `${prefix}:*`}); } ``` -------------------------------- ### Environment Variables for Redis and Session Configuration Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Configure Redis connection details and session prefix using a .env file. Copy .env.example to .env and update with your Redis credentials. ```bash # Redis Configuration REDIS_HOST=localhost # Redis server hostname REDIS_PORT=6379 # Redis server port REDIS_PASSWORD=your_password # Redis password (optional) # Baileys Session Prefix SESSION_PREFIX=session # Session identifier prefix (default: 'session') ``` -------------------------------- ### Format Code with Biome Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Formats the codebase using Biome for consistent code style. ```bash bun run format ``` -------------------------------- ### Clone Repository Bash Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Clone the repository to your local machine. Navigate into the cloned directory. ```bash git clone https://github.com/hbinduni/baileys-redis-auth.git cd baileys-redis-auth ``` -------------------------------- ### Build Library Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Builds the TypeScript library, outputting to the lib/ directory. This command automatically runs type checking and linting before building. ```bash bun run build ``` -------------------------------- ### Check Formatting and Linting Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Combines code formatting and linting checks. ```bash bun run check ``` -------------------------------- ### Session Cleanup on Logout Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Demonstrates how to properly implement session cleanup in Redis when a user logs out of WhatsApp, by leveraging the `connection.update` event and `deleteKeysWithPattern`. ```APIDOC ## Proper Logout Implementation ### Description When `sock.logout()` is called, Baileys does not automatically clear the Redis session. This section shows how to manually handle session cleanup in your `connection.update` event handler. ### Method This involves listening to the `connection.update` event and calling `deleteKeysWithPattern` when the connection closes due to `DisconnectReason.loggedOut`. ### Parameters - `redis`: An active `ioredis` client instance. - `sessionId`: The identifier of the session to clean up. - `logger` (optional): A function for logging scan operations. ### Request Example ```typescript import { deleteKeysWithPattern, useRedisAuthState } from 'baileys-redis-auth' import makeWASocket, { DisconnectReason } from 'baileys' import type { Boom } from '@hapi/boom' const sessionId = 'my-session' const { state, saveCreds, redis } = await useRedisAuthState( redisOptions, sessionId, console.log ) const sock = makeWASocket({ auth: state }) // Handle connection updates sock.ev.on('connection.update', async (update) => { const { connection, lastDisconnect } = update if (connection === 'close') { const statusCode = (lastDisconnect?.error as Boom)?.output?.statusCode if (statusCode === DisconnectReason.loggedOut) { // Clear Redis session on logout await deleteKeysWithPattern({ redis, sessionId: sessionId, logger: console.log // Optional: pass logger for debugging }) console.log('Session cleared') } } }) // When you want to logout await sock.logout() // Session cleanup happens in connection.update handler ``` ``` -------------------------------- ### Initializing State with `useRedisAuthState` Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Initializes the Baileys authentication state using Redis, storing each piece of data as a separate key-value pair. ```APIDOC ## Using `useRedisAuthState` ### Description This method stores each piece of authentication data as a separate key-value pair in Redis, prefixed by the `sessionId` string. While functional, it can lead to a larger number of individual keys in your Redis database compared to the HSET method. ### Parameters - `redisOptions` (object) - Required: An object containing your Redis server connection details (e.g., `host`, `port`, `password`). This is passed directly to the `ioredis` constructor. - `sessionId` (string) - Required: A string used to identify and prefix all Redis keys for this Baileys session. For example, if your `sessionId` is `'user-456'`, keys will be stored like `user-456:creds`, `user-456:pre-key-1`, etc. - `logger` (function) - Optional: A function `(message: string, ...args: unknown[]) => void` for logging Redis connection events. Pass `console.log` or your custom logger function. ### Request Example ```typescript import { useRedisAuthState, deleteKeysWithPattern } from 'baileys-redis-auth' import Redis, { RedisOptions } from 'ioredis' // Define your Redis connection options const redisOptions: RedisOptions = { host: 'localhost', port: 6379 // password: 'your_redis_password', // Uncomment if your Redis has a password } // Define a unique session identifier for this Baileys session const sessionId = 'baileys_session_2' async function initializeBaileysSimple() { // useRedisAuthState creates its own Redis instance internally based on redisOptions const { state, saveCreds, redis: authRedisInstance } = await useRedisAuthState( redisOptions, sessionId, console.log // Optional: pass logger for Redis connection events ) // 'state' will be used to initialize Baileys // 'saveCreds' is a function to periodically save the authentication state // 'authRedisInstance' is the Redis client instance used by the auth state hook console.log('Baileys state loaded using simple key-value method.') // Example: Listen for Redis connection events on the instance returned by the hook authRedisInstance.on('connect', () => console.log(`Redis (from hook) connected for session: ${sessionId}`) ) authRedisInstance.on('error', (err) => console.error(`Redis (from hook) error for session ${sessionId}:`, err) ) // ... your Baileys setup code using 'state' and 'saveCreds' // Example of how to delete all keys for this specific session if needed: // await deleteKeysWithPattern({redis: authRedisInstance, sessionId: sessionId}); // console.log(`Authentication data for session ${sessionId} deleted.`); } initializeBaileysSimple().catch(console.error) ``` ``` -------------------------------- ### Clean Build Directory Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Cleans the build directory before a new build. ```bash bun run clean ``` -------------------------------- ### Initialize HSet-based Auth State with Baileys Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Use `useRedisAuthStateWithHSet` for memory-efficient session storage. Ensure Redis is running and accessible. The logger is optional. ```typescript import makeWASocket, { DisconnectReason, makeCacheableSignalKeyStore } from 'baileys' import { useRedisAuthStateWithHSet, deleteHSetKeys } from 'baileys-redis-auth' import type { Boom } from '@hapi/boom' const redisOptions = { host: 'localhost', port: 6379 } const sessionId = 'whatsapp-bot-1' const { state, saveCreds, redis } = await useRedisAuthStateWithHSet( redisOptions, sessionId, console.log // optional logger ) const sock = makeWASocket({ auth: { creds: state.creds, keys: makeCacheableSignalKeyStore(state.keys, console.log), }, }) // Persist credentials whenever they change sock.ev.on('creds.update', saveCreds) sock.ev.on('connection.update', async ({ connection, lastDisconnect, qr }) => { if (qr) console.log('Scan QR:', qr) if (connection === 'open') { console.log('Connected as:', sock.user?.name) } if (connection === 'close') { const code = (lastDisconnect?.error as Boom)?.output?.statusCode if (code === DisconnectReason.loggedOut) { // Must manually clear Redis on logout await deleteHSetKeys({ redis, sessionId, logger: console.log }) console.log('Session cleared from Redis') } } }) // Redis key created: "whatsapp-bot-1:auth" (Hash) ``` -------------------------------- ### Git Branching for Contributions Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Standard Git commands for creating a new branch for feature development. Follow these steps when contributing to the project. ```bash git checkout -b feature/your-feature-name ``` -------------------------------- ### Initialize Baileys with Redis AuthState (useRedisAuthState) Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Initialize Baileys authentication state using `useRedisAuthState`, which stores each auth piece as a separate key-value pair in Redis, prefixed by the session ID. This method creates its own Redis instance internally. It returns the authentication state, a function to save credentials, and the Redis client instance. ```typescript import { useRedisAuthState, deleteKeysWithPattern } from 'baileys-redis-auth' import Redis, { RedisOptions } from 'ioredis' // Define your Redis connection options const redisOptions: RedisOptions = { host: 'localhost', port: 6379 // password: 'your_redis_password', // Uncomment if your Redis has a password } // Define a unique session identifier for this Baileys session const sessionId = 'baileys_session_2' async function initializeBaileysSimple() { // useRedisAuthState creates its own Redis instance internally based on redisOptions const { state, saveCreds, redis: authRedisInstance } = await useRedisAuthState( redisOptions, sessionId, console.log // Optional: pass logger for Redis connection events ) // 'state' will be used to initialize Baileys // 'saveCreds' is a function to periodically save the authentication state // 'authRedisInstance' is the Redis client instance used by the auth state hook console.log('Baileys state loaded using simple key-value method.') // Example: Listen for Redis connection events on the instance returned by the hook authRedisInstance.on('connect', () => console.log(`Redis (from hook) connected for session: ${sessionId}`) ) authRedisInstance.on('error', (err) => console.error(`Redis (from hook) error for session ${sessionId}:`, err) ) // ... your Baileys setup code using 'state' and 'saveCreds' // Example of how to delete all keys for this specific session if needed: // await deleteKeysWithPattern({redis: authRedisInstance, sessionId: sessionId}); // console.log(`Authentication data for session ${sessionId} deleted.`); } initializeBaileysSimple().catch(console.error) ``` -------------------------------- ### Check and Auto-fix Formatting and Linting Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Checks code formatting and linting, and automatically applies fixes. ```bash bun run check:fix ``` -------------------------------- ### Redis Hash State Storage (HSET) Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Recommended implementation for storing authentication data in a single Redis Hash per session. Uses HSET, HGET, HDEL operations for efficiency. File names are sanitized for safe Redis key naming. ```typescript import { useRedisAuthStateWithHSet } from 'baileys-redis-auth'; // Example usage: const { state, saveCreds, redis } = await useRedisAuthStateWithHSet({ redis: redisClient, prefix: 'session', }); ``` -------------------------------- ### Initialize Key-Value Auth State with Baileys Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Use `useRedisAuthState` for granular control over session data stored as individual Redis keys. Supports password-protected Redis instances. ```typescript import makeWASocket, { DisconnectReason } from 'baileys' import { useRedisAuthState, deleteKeysWithPattern } from 'baileys-redis-auth' import type { Boom } from '@hapi/boom' const { state, saveCreds, redis } = await useRedisAuthState( { host: 'localhost', port: 6379, password: process.env.REDIS_PASSWORD }, 'my-session', console.log ) const sock = makeWASocket({ auth: state }) sock.ev.on('creds.update', saveCreds) sock.ev.on('connection.update', async ({ connection, lastDisconnect }) => { if (connection === 'close') { const code = (lastDisconnect?.error as Boom)?.output?.statusCode const shouldReconnect = code !== DisconnectReason.loggedOut if (shouldReconnect) { console.log('Reconnecting...') // restart your startSock() function here } else { await deleteKeysWithPattern({ redis, sessionId: 'my-session', logger: console.log }) console.log('Logged out and session cleared') } } }) // Redis keys created: "my-session:creds", "my-session:pre-key-1", etc. ``` -------------------------------- ### Git Commit and Push for Contributions Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Commands to commit your changes and push them to a remote branch. Essential for submitting pull requests. ```bash git commit -m 'Add some feature' git push origin feature/your-feature-name ``` -------------------------------- ### Initiate Logout Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/LOGOUT_GUIDE.md Call this function when the user explicitly requests to log out. The connection handler will manage the session cleanup. ```typescript // When user wants to logout try { await sock.logout() } catch (error) { // Logout throws "Intentional Logout" error - this is expected // The connection.update handler will handle cleanup } ``` -------------------------------- ### List Hash-based Sessions with `listHSetSessions` Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Scans Redis for hash keys matching `*:auth` and returns session identifiers. Useful for dashboards or auditing. ```typescript import { listHSetSessions, deleteHSetKeys } from 'baileys-redis-auth' import Redis from 'ioredis' const redis = new Redis({ host: 'localhost', port: 6379 }) const sessions = await listHSetSessions({ redis, logger: console.log }) // Logs: "Scanning for Hash-based sessions..." // Logs: "Found 3 Hash-based sessions" console.log('Active sessions:', sessions) // Output: ['bot-1', 'bot-2', 'user-abc'] // Clean up a stale session if (sessions.includes('bot-2')) { await deleteHSetKeys({ redis, sessionId: 'bot-2' }) console.log('Removed stale session bot-2') } await redis.quit() ``` -------------------------------- ### Full Check: Typecheck and Lint Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Performs a comprehensive check including TypeScript type checking and linting. ```bash bun run check:all ``` -------------------------------- ### Full Check and Fix: Typecheck and Auto-fix Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Performs a comprehensive check including type checking and automatically fixing code issues. ```bash bun run check:all:fix ``` -------------------------------- ### List Key-Value Sessions with `listSessions` Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Scans Redis for keys matching `*:creds`, extracts unique session identifiers, and returns them. Uses a Set internally for deduplication. ```typescript import { listSessions, deleteKeysWithPattern } from 'baileys-redis-auth' import Redis from 'ioredis' const redis = new Redis({ host: 'localhost', port: 6379 }) const sessions = await listSessions({ redis, logger: console.log }) // Logs: "Scanning for key-value based sessions..." // Logs: "Found 2 key-value based sessions" console.log('Sessions:', sessions) // Output: ['my-session', 'session-456'] // Bulk cleanup of all discovered sessions for (const sessionId of sessions) { await deleteKeysWithPattern({ redis, sessionId }) console.log(`Cleared session: ${sessionId}`) } await redis.quit() ``` -------------------------------- ### useRedisAuthStateWithHSet Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Initializes Baileys authentication state using a Redis Hash for each session. This method is recommended for its efficiency and reduced Redis command overhead. ```APIDOC ## useRedisAuthStateWithHSet ### Description Initializes Baileys authentication state backed by a single Redis Hash per session. All credentials and Signal keys are stored as fields of one hash key (`{sessionId}:auth`), making it memory-efficient and reducing Redis command overhead via parallel `HSET`/`HGET`/`HDEL` operations. ### Method ```typescript useRedisAuthStateWithHSet(redisOptions: RedisOptions, sessionId: string, logger?: LoggerFunction): Promise<{ state: AuthState, saveCreds: () => void, redis: Redis }>; ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import makeWASocket, { DisconnectReason, makeCacheableSignalKeyStore } from 'baileys' import { useRedisAuthStateWithHSet, deleteHSetKeys } from 'baileys-redis-auth' import type { Boom } from '@hapi/boom' const redisOptions = { host: 'localhost', port: 6379 } const sessionId = 'whatsapp-bot-1' const { state, saveCreds, redis } = await useRedisAuthStateWithHSet( redisOptions, sessionId, console.log // optional logger ) const sock = makeWASocket({ auth: { creds: state.creds, keys: makeCacheableSignalKeyStore(state.keys, console.log), }, }) // Persist credentials whenever they change sock.ev.on('creds.update', saveCreds) sock.ev.on('connection.update', async ({ connection, lastDisconnect, qr }) => { if (qr) console.log('Scan QR:', qr) if (connection === 'open') { console.log('Connected as:', sock.user?.name) } if (connection === 'close') { const code = (lastDisconnect?.error as Boom)?.output?.statusCode if (code === DisconnectReason.loggedOut) { // Must manually clear Redis on logout await deleteHSetKeys({ redis, sessionId, logger: console.log }) console.log('Session cleared from Redis') } } }) // Redis key created: "whatsapp-bot-1:auth" (Hash) ``` ### Response #### Success Response (200) Returns an object containing: - `state`: The authentication state for Baileys (`{ creds, keys }`). - `saveCreds`: A function to save updated credentials. - `redis`: The `ioredis` client instance. #### Response Example ```json { "state": { "creds": { ... }, "keys": { ... } }, "saveCreds": "function", "redis": "ioredis_instance" } ``` ``` -------------------------------- ### Handle Logout Cleanup in Connection Update Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/LOGOUT_GUIDE.md Listen for the 'connection.update' event and trigger cleanup using `deleteKeysWithPattern` when the connection closes due to logout. Note that `sock.logout()` handles cleanup automatically. ```typescript sock.ev.on('connection.update', async (update) => { if (connection === 'close' && statusCode === DisconnectReason.loggedOut) { await deleteKeysWithPattern({redis, sessionId: 'session'}) } }) // Later... await sock.logout() // Cleanup happens automatically ``` -------------------------------- ### List Hash-Based Sessions with baileys-redis-auth Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Use `listHSetSessions` to retrieve all session identifiers stored using the `useRedisAuthStateWithHSet` method. Requires an active ioredis client instance. An optional logger can be provided for debugging scan operations. ```typescript import { listHSetSessions } from 'baileys-redis-auth' import Redis from 'ioredis' const redis = new Redis({ host: 'localhost', port: 6379 }) async function showAllHashSessions() { const sessions = await listHSetSessions({ redis, logger: console.log // Optional: pass logger for debugging }) console.log('Active Hash-based sessions:', sessions) // Output: ['baileys_session_1', 'user-123', 'bot-789'] // You can now iterate and manage these sessions for (const sessionId of sessions) { console.log(`Found session: ${sessionId}`) } } showAllHashSessions().catch(console.error) ``` -------------------------------- ### List Key-Value Based Sessions with baileys-redis-auth Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Use `listSessions` to retrieve all session identifiers stored using the `useRedisAuthState` method. Requires an active ioredis client instance. An optional logger can be provided for debugging scan operations. ```typescript import { listSessions } from 'baileys-redis-auth' import Redis from 'ioredis' const redis = new Redis({ host: 'localhost', port: 6379 }) async function showAllKeyValueSessions() { const sessions = await listSessions({ redis, logger: console.log // Optional: pass logger for debugging }) console.log('Active key-value based sessions:', sessions) // Output: ['baileys_session_2', 'user-456', 'bot-012'] // You can now iterate and manage these sessions for (const sessionId of sessions) { console.log(`Found session: ${sessionId}`) } } showAllKeyValueSessions().catch(console.error) ``` -------------------------------- ### listHSetSessions Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Scans Redis for all hash keys matching `*:auth` and returns an array of session identifiers by stripping the `:auth` suffix. This is useful for building session management dashboards or auditing active connections. ```APIDOC ## listHSetSessions ### Description Scans Redis for all hash keys matching `*:auth` and returns an array of session identifiers by stripping the `:auth` suffix. Useful for building session management dashboards or auditing active connections. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **redis** (RedisClient) - Required - The Redis client instance. - **logger** (function) - Optional - A function for logging information. ### Request Example ```typescript import { listHSetSessions, deleteHSetKeys } from 'baileys-redis-auth'; import Redis from 'ioredis'; const redis = new Redis({ host: 'localhost', port: 6379 }); const sessions = await listHSetSessions({ redis, logger: console.log }); // Logs: "Scanning for Hash-based sessions..." // Logs: "Found 3 Hash-based sessions" console.log('Active sessions:', sessions); // Output: ['bot-1', 'bot-2', 'user-abc'] // Clean up a stale session if (sessions.includes('bot-2')) { await deleteHSetKeys({ redis, sessionId: 'bot-2' }); console.log('Removed stale session bot-2'); } await redis.quit(); ``` ### Response #### Success Response (200) - **sessions** (string[]) - An array of session identifiers. #### Response Example ```json ["bot-1", "bot-2", "user-abc"] ``` ``` -------------------------------- ### listSessions Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Lists all session identifiers stored using the `useRedisAuthState` method. Useful for discovering active Key-Value based sessions. ```APIDOC ## listSessions ### Description Lists all session identifiers stored using the `useRedisAuthState` method. ### Method `listSessions(options: { redis: Redis; logger?: Function }) => Promise` ### Parameters #### Options - **redis** (Redis) - Required - An active `ioredis` client instance. - **logger** (Function) - Optional - A function for logging scan operations. ### Returns `Promise` - An array of unique session identifiers. ### Request Example ```typescript import { listSessions } from 'baileys-redis-auth' import Redis from 'ioredis' const redis = new Redis({ host: 'localhost', port: 6379 }) async function showAllKeyValueSessions() { const sessions = await listSessions({ redis, logger: console.log // Optional: pass logger for debugging }) console.log('Active key-value based sessions:', sessions) } showAllKeyValueSessions().catch(console.error) ``` ``` -------------------------------- ### useRedisAuthState Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Initializes Baileys authentication state using individual Redis string keys for each authentication piece. This method offers granular TTL control and broader compatibility. ```APIDOC ## useRedisAuthState ### Description Initializes Baileys authentication state using individual Redis string keys per auth piece, stored under the pattern `{sessionId}:{key}` (e.g., `my-session:creds`, `my-session:pre-key-1`). This approach creates more keys but offers granular TTL control and broader compatibility with existing Redis tooling. ### Method ```typescript useRedisAuthState(redisOptions: RedisOptions, sessionId: string, logger?: LoggerFunction): Promise<{ state: AuthState, saveCreds: () => void, redis: Redis }>; ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import makeWASocket, { DisconnectReason } from 'baileys' import { useRedisAuthState, deleteKeysWithPattern } from 'baileys-redis-auth' import type { Boom } from '@hapi/boom' const { state, saveCreds, redis } = await useRedisAuthState( { host: 'localhost', port: 6379, password: process.env.REDIS_PASSWORD }, 'my-session', console.log ) const sock = makeWASocket({ auth: state }) sock.ev.on('creds.update', saveCreds) sock.ev.on('connection.update', async ({ connection, lastDisconnect }) => { if (connection === 'close') { const code = (lastDisconnect?.error as Boom)?.output?.statusCode const shouldReconnect = code !== DisconnectReason.loggedOut if (shouldReconnect) { console.log('Reconnecting...') // restart your startSock() function here } else { await deleteKeysWithPattern({ redis, sessionId: 'my-session', logger: console.log }) console.log('Logged out and session cleared') } } }) // Redis keys created: "my-session:creds", "my-session:pre-key-1", etc. ``` ### Response #### Success Response (200) Returns an object containing: - `state`: The authentication state for Baileys (`{ creds, keys }`). - `saveCreds`: A function to save updated credentials. - `redis`: The `ioredis` client instance. #### Response Example ```json { "state": { "creds": { ... }, "keys": { ... } }, "saveCreds": "function", "redis": "ioredis_instance" } ``` ``` -------------------------------- ### Incorrect Logout: Missing Cleanup Handler Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/LOGOUT_GUIDE.md This code snippet demonstrates an incorrect approach where `sock.logout()` is called without a corresponding handler to clear the Redis session, leaving stale data. ```typescript // This will NOT clear your Redis session! await sock.logout() // Session data still exists in Redis ``` -------------------------------- ### Initialize Baileys with Redis HSet Auth State Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Use `useRedisAuthStateWithHSet` to store Baileys authentication data in Redis using Hashes. This method is efficient for managing multiple sessions. It requires Redis connection options and a unique session ID. The hook returns the Baileys state, a save function, and the Redis client instance. ```typescript import { useRedisAuthStateWithHSet, deleteHSetKeys } from 'baileys-redis-auth' import Redis, { RedisOptions } from 'ioredis' // Define your Redis connection options const redisOptions: RedisOptions = { host: 'localhost', port: 6379 // password: 'your_redis_password', // Uncomment if your Redis has a password } // Define a unique session identifier for this Baileys session const sessionId = 'baileys_session_1' async function initializeBaileysWithHSet() { // useRedisAuthStateWithHSet creates its own Redis instance internally based on redisOptions const { state, saveCreds, redis: authRedisInstance } = await useRedisAuthStateWithHSet( redisOptions, sessionId, console.log // Optional: pass logger for Redis connection events ) // 'state' will be used to initialize Baileys // 'saveCreds' is a function to periodically save the authentication state // 'authRedisInstance' is the Redis client instance used by the auth state hook console.log('Baileys state loaded using HSet method.') // Example: Listen for Redis connection events on the instance returned by the hook authRedisInstance.on('connect', () => console.log(`Redis (from hook) connected for session: ${sessionId}`) ) authRedisInstance.on('error', (err) => console.error(`Redis (from hook) error for session ${sessionId}:`, err) ) // ... your Baileys setup code using 'state' and 'saveCreds' // Example of how to delete all data for this specific session if needed: // await deleteHSetKeys({redis: authRedisInstance, sessionId: sessionId}); // console.log(`Authentication data for session ${sessionId} deleted.`); } initializeBaileysWithHSet().catch(console.error) ``` -------------------------------- ### Delete Keys with Pattern (Key-Value Storage) Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/LOGOUT_GUIDE.md Use this function to delete keys from Redis based on a pattern, typically for session cleanup. It requires a Redis client and a session ID. ```typescript deleteKeysWithPattern({ redis: RedisClient, // Redis client from useRedisAuthState sessionId: string, // Session ID (e.g., 'session') logger?: (message: string, ...args: unknown[]) => void // Optional logger function }): Promise ``` -------------------------------- ### TypeScript Type Checking Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Performs TypeScript type checking on the codebase. ```bash bun run typecheck ``` -------------------------------- ### Proper Baileys Logout and Redis Session Cleanup Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Implement session cleanup in the `connection.update` event handler. When the connection closes with `DisconnectReason.loggedOut`, use `deleteKeysWithPattern` to clear the corresponding Redis session. This ensures no orphaned session data remains after logout. ```typescript import { deleteKeysWithPattern, useRedisAuthState } from 'baileys-redis-auth' import makeWASocket, { DisconnectReason } from 'baileys' import type { Boom } from '@hapi/boom' const sessionId = 'my-session' const { state, saveCreds, redis } = await useRedisAuthState( redisOptions, sessionId, console.log ) const sock = makeWASocket({ auth: state }) // Handle connection updates sock.ev.on('connection.update', async (update) => { const { connection, lastDisconnect } = update if (connection === 'close') { const statusCode = (lastDisconnect?.error as Boom)?.output?.statusCode if (statusCode === DisconnectReason.loggedOut) { // Clear Redis session on logout await deleteKeysWithPattern({ redis, sessionId: sessionId, logger: console.log // Optional: pass logger for debugging }) console.log('Session cleared') } } }) // When you want to logout await sock.logout() // Session cleanup happens in connection.update handler ``` -------------------------------- ### listHSetSessions Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/README.md Lists all session identifiers stored using the `useRedisAuthStateWithHSet` method. Useful for discovering active Hash-based sessions. ```APIDOC ## listHSetSessions ### Description Lists all session identifiers stored using the `useRedisAuthStateWithHSet` method. ### Method `listHSetSessions(options: { redis: Redis; logger?: Function }) => Promise` ### Parameters #### Options - **redis** (Redis) - Required - An active `ioredis` client instance. - **logger** (Function) - Optional - A function for logging scan operations. ### Returns `Promise` - An array of session identifiers. ### Request Example ```typescript import { listHSetSessions } from 'baileys-redis-auth' import Redis from 'ioredis' const redis = new Redis({ host: 'localhost', port: 6379 }) async function showAllHashSessions() { const sessions = await listHSetSessions({ redis, logger: console.log // Optional: pass logger for debugging }) console.log('Active Hash-based sessions:', sessions) } showAllHashSessions().catch(console.error) ``` ``` -------------------------------- ### Detect Logout and Clear Redis Session Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/LOGOUT_GUIDE.md Implement this in your connection handler to clear the Redis session when a user logs out. Ensure the `sessionId` matches your session prefix. ```typescript import { deleteKeysWithPattern, useRedisAuthState } from 'baileys-redis-auth' import {DisconnectReason} from 'baileys' const {state, saveCreds, redis} = await useRedisAuthState(redisOptions, 'my-session') sock.ev.on('connection.update', async (update) => { const {connection, lastDisconnect} = update if (connection === 'close') { const statusCode = (lastDisconnect?.error as Boom)?.output?.statusCode if (statusCode === DisconnectReason.loggedOut) { // User logged out - clear the session await deleteKeysWithPattern({ redis, sessionId: 'my-session', // Must match your session prefix logger: console.log // Optional: pass logger for debugging }) console.log('Session cleared after logout') } } }) ``` -------------------------------- ### Delete Key-Value Session State with `deleteKeysWithPattern` Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Removes all Redis string keys matching `{sessionId}:*` for a session. Uses a non-blocking SCAN + UNLINK loop for safe iteration. ```typescript import { useRedisAuthState, deleteKeysWithPattern } from 'baileys-redis-auth' const { redis } = await useRedisAuthState( { host: 'localhost', port: 6379 }, 'session-456' ) try { await deleteKeysWithPattern({ redis, sessionId: 'session-456', logger: console.log, }) // Logs: "Removing auth state for session: session-456" // Scans and unlinks all keys matching "session-456:*" console.log('All session keys removed') } catch (err) { console.error('Failed to remove session keys:', err) } ``` -------------------------------- ### listSessions Source: https://context7.com/hbinduni/baileys-redis-auth/llms.txt Scans Redis for all keys matching `*:creds`, extracts unique session identifiers, and returns them as an array. This function works with sessions created by `useRedisAuthState` and uses a `Set` internally to deduplicate results. ```APIDOC ## listSessions ### Description Scans Redis for all keys matching `*:creds`, extracts unique session identifiers, and returns them as an array. Works with sessions created by `useRedisAuthState`. Uses a `Set` internally to deduplicate results. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **redis** (RedisClient) - Required - The Redis client instance. - **logger** (function) - Optional - A function for logging information. ### Request Example ```typescript import { listSessions, deleteKeysWithPattern } from 'baileys-redis-auth'; import Redis from 'ioredis'; const redis = new Redis({ host: 'localhost', port: 6379 }); const sessions = await listSessions({ redis, logger: console.log }); // Logs: "Scanning for key-value based sessions..." // Logs: "Found 2 key-value based sessions" console.log('Sessions:', sessions); // Output: ['my-session', 'session-456'] // Bulk cleanup of all discovered sessions for (const sessionId of sessions) { await deleteKeysWithPattern({ redis, sessionId }); console.log(`Cleared session: ${sessionId}`); } await redis.quit(); ``` ### Response #### Success Response (200) - **sessions** (string[]) - An array of unique session identifiers. #### Response Example ```json ["my-session", "session-456"] ``` ``` -------------------------------- ### Delete Keys with Pattern Source: https://github.com/hbinduni/baileys-redis-auth/blob/main/CLAUDE.md Cleans up authentication data stored as individual keys in Redis using a pattern. ```typescript import { deleteKeysWithPattern } from 'baileys-redis-auth'; // Example usage: await deleteKeysWithPattern({ redis: redisClient, pattern: 'session:*' }); ```