Created by Yuval Avidani | 2x GitHub Star ⭐⭐ | 2x AWS Gen AI Superstar 🌟🌟 | AI Speaker & Builder
Note: This is an unofficial, community-maintained implementation of a WhatsApp AI bot. It is not affiliated with or endorsed by WhatsApp, Meta, or any official Logan project.
A powerful, self-hosted WhatsApp bot built with Node.js and Baileys that brings AI intelligence to your WhatsApp groups. Logan provides intelligent group management, AI-powered responses, daily summaries, voice transcription, and automated Shabbat scheduling.
Built with ❤️ for the open source community by @hoodini
GitHub • Twitter/X • Instagram • YouTube • Blog • Linktree
- What is Logan?
- Features
- Prerequisites
- Quick Start
- Detailed Setup Guide
- Configuration
- Security
- API Endpoints
- Architecture
- Troubleshooting
- Contributing
- License
Logan is a self-hosted WhatsApp bot that runs on your own server/computer using your own WhatsApp account. Think of it as your personal AI assistant that lives inside WhatsApp groups.
- 📝 Logs all group messages to a database for archival and analysis
- 🤖 Responds intelligently when @mentioned, using AI to understand context
- 📊 Generates daily summaries of group discussions automatically
- 🎤 Transcribes voice messages so you can read instead of listen
- 🕯️ Respects Shabbat by automatically locking groups before Shabbat and unlocking after havdalah
- 🚫 Detects and removes spam using AI-powered analysis
- 🔊 Creates voice summaries using text-to-speech for accessibility
- Privacy-First: Your data stays on your own infrastructure (Supabase account)
- Customizable: Full control over behavior, scheduling, and features
- Open Source: Inspect, modify, and extend the code as you wish
- Community-Driven: Built by the community, for the community
- Hebrew Support: Built with Hebrew-speaking communities in mind
Logan is packed with features designed for intelligent group management and AI-powered interactions.
- Context-Aware Conversations: Logan understands conversation context from recent messages (15 group messages, 5 user messages)
- Multi-Language Support: Works in Hebrew, English, and mixed conversations
- Personality: Warm, helpful, and culturally aware (Israeli tech community optimized)
- Smart Triggers: Responds to @mentions, "logan", "לוגן" keywords
- Rate Limiting: 3 responses per user per minute to prevent spam
- LLM Backend: Powered by Groq API (LLaMA 3.3 70B / GPT-4 class performance)
- Automated Daily Recaps: AI-generated summaries of group discussions at scheduled time (default 22:00 Israel time)
- Multi-Group Support: Can summarize multiple groups separately
- Master Channel: Optional unified summary combining all groups
- Erev Shabbat Awareness: Sends summaries early (30 min before candle lighting) on Friday
- Smart Filtering: Only includes meaningful content (ignores system messages)
- LLM Backend: Powered by Claude 3.5 Sonnet for high-quality summaries
- Voice Message Transcription: Automatic transcription of voice messages using Whisper (Groq)
- Voice Summaries: Text-to-speech summaries using ElevenLabs TTS (optional)
- Anti-Cutoff: Smart chunking prevents voice messages from cutting mid-sentence
- Hebrew Support: Handles Hebrew text-to-speech naturally
- Real-Time Search: Fetches fresh data from the web via Tavily API
- Source Citations: Always includes sources with URLs
- Hallucination Detection: Detects and filters fake URLs from LLM responses
- Smart Triggers: Activates for queries needing current information
- Cached Results: 2-hour cache to save API calls
- Authorization: Configurable per-user or per-group access
The most comprehensive Shabbat protection system:
-
Hebcal API Integration
- Fetches candle lighting and havdalah times for any city worldwide
- Supports configurable offsets (e.g., -30 min before, +30 min after)
- Different locations for lock/unlock (lock in Jerusalem, unlock in Tel Aviv)
-
Cache Layer
- Local cache file (
shabbat_times_cache.json) prevents API failures - Updates automatically every Friday morning
- Fallback if API is unreachable
- Local cache file (
-
Lock State File
- Persistent state tracking (
shabbat_lock_state.json) - Survives restarts and reconnects
- Prevents duplicate lock/unlock operations
- Persistent state tracking (
-
Timezone Fallback
- If all else fails, uses Israel timezone assumptions
- Friday 3 PM → Saturday 9 PM default window
How it Works:
- Before Shabbat: Groups set to "announcement mode" (only admins can post)
- After Havdalah: Groups unlocked with "שבוע טוב" greeting
- All Paths Protected: Every message-sending function checks Shabbat status
- Early Check: Shabbat checked 3 seconds after connection (before stability timer)
- AI-Powered Detection: LLM analyzes message context, not just keywords
- Two-Strike System:
- First offense: Warning message
- Second offense: Automatic removal from group
- Pre-Filter: Catches obvious spam before LLM analysis (saves API costs)
- Whitelist Support: Protect trusted users from false positives
- Admin Notifications: DMs admins when spam is detected or removed
- Configurable: Enable/disable per group or globally
Intelligent bot detection and auto-approval:
-
Bot Detection Algorithm:
- No profile picture: +2 suspicion score
- Bot-like name patterns: +2 suspicion score
- Suspicious phone number patterns: +1 suspicion score
- Threshold ≥3: Auto-reject (likely bot)
- Threshold <3: Auto-approve (likely human)
-
Group Size Enforcement: Configurable max members (default 1024)
-
Daily Processing: Automated check at scheduled time (default 09:00)
-
Shabbat Aware: Skips processing during Shabbat
-
Admin Notifications: DMs admins with processing results
-
Manual Override: Script for manual processing when needed
- Multi-Group Announcements: Send messages to all monitored groups at once
- Duplicate Prevention: Supabase-backed atomic locks prevent double-sends
- Partial Recovery: Tracks which groups received message if interrupted
- Race Condition Protection: Handles multiple bot instances running simultaneously
- Restart Resilience: Survives bot restarts mid-broadcast
- Complete Archive: All group messages logged to Supabase PostgreSQL database
- Rich Metadata: Sender, timestamp, message type, group info, from_me flag
- Content Types: Text, images, videos, audio, documents, stickers, voice, polls, locations
- System Messages: Optional logging of joins, leaves, admin changes
- Privacy Controls: Configure which groups to monitor via
ALLOWED_GROUPS
- Database-Backed Sessions: WhatsApp multi-device session stored in Supabase
- Persistent Across Restarts: No need to re-scan QR after restarts
- Sync Across Instances: Multiple instances can share auth state
- Automatic Cleanup: Old session data automatically purged
- Operation Tracking: Tracks all broadcast operations (daily summaries, Shabbat locks)
- Atomic Locking: Prevents race conditions between multiple instances
- Status Tracking: started → completed/failed
- Partial State: Remembers which groups received message for recovery
- Failed Message Retry: Stores responses that couldn't be delivered
- Automatic Retry: Retries when connection restored
- Response Types: Landing pages, videos, agent responses
- Retry Tracking: Counts retry attempts
-
Multi-Tier Access Control:
- Admin Numbers: Full access to all features in any group/DM
- Public Groups: All users can use features in specific groups
- Free Chat Groups: All users can text chat (no tools)
-
Feature-Specific Auth: Separate auth for agent, mentions, Tavily search
-
Admin-Only Mode: Lock down bot to admins only for testing
-
Flexible Configuration: Mix public groups + admin users
- Exponential Backoff: Smart retry with jitter for 440 errors
- Session Replaced Handling: Detects and recovers from multiple device conflicts
- Stability Timer: 10-second wait before "stable" confirmation
- Early Shabbat Check: Validates Shabbat status at 3 seconds (before stability timer)
- Conservative Settings: Tuned WebSocket settings to prevent bans
- Per-User Rate Limit: 3 responses per user per minute
- Daily Summary Cooldown: 1 summary per group per 23 hours
- Voice Summary Cooldown: Prevents spam of TTS messages
- API Token Tracking: Monitors Groq daily token usage (200K limit)
- Selective Monitoring: Choose which groups to monitor via
ALLOWED_GROUPSJSON array - Default All-Groups: Monitors all groups if not configured
- Priority Ordering: Lock/unlock groups in specified order
- Channel Support: Handles WhatsApp Channels (newsletters)
- REST API: Express server on port 7700 (configurable)
- Authentication: Optional API key protection
- Health Checks:
/api/healthendpoint with connection status - Message Queue:
/api/queueshows pending operations - Group List:
/api/groupsreturns all monitored groups - Manual Triggers: Endpoints to manually trigger summaries, lock/unlock, etc.
- 90+ Environment Variables: Every behavior is configurable
- JSON Configuration: Group lists, admin lists via JSON in env vars
- Feature Flags: Enable/disable any feature independently
- Time Scheduling: Configure times for summaries, join processing, etc.
- Modular Services: Groq, Claude, Tavily, ElevenLabs, Whisper services
- Feature Modules: Daily summary, mention response, broadcast as separate modules
- Event-Driven: Message handler dispatches to appropriate features
- Database-First: Supabase for state, messages, auth, guards
- Structured Logging: Pino logger with configurable levels (info/debug/warn/error)
- Operation Tracking: All broadcasts, summaries tracked in database
- Error Handling: Graceful error recovery with detailed logging
- Debug Scripts: Included scripts for debugging admin status, join requests
- Type Safety: Full TypeScript codebase
- Interfaces: Clear type definitions for messages, configs, responses
- Compile-Time Checks: Catch errors before runtime
- IDE Support: IntelliSense and autocomplete
- Hebrew Primary: Built for Hebrew-speaking communities
- English Support: Full English language support
- Mixed Conversations: Handles Hebrew + English naturally
- Hebrew Calendar: Integrates with Jewish calendar (Hebcal)
- Israeli Timezone: Defaults to Asia/Jerusalem timezone
- Cultural Awareness: Shabbat greetings, Israeli tech community tone
Before you begin, make sure you have:
- Node.js 18+ - Download here
- A spare WhatsApp account - Cannot use your main WhatsApp on the same device
- Get a new SIM card or Google Voice number
- This will become the bot's WhatsApp account
- Supabase account - Sign up free
- Free tier includes: 500MB database, 2GB bandwidth/month
- Used for message storage and state management
- API Keys (all have free tiers):
- Groq API - For AI responses (200K tokens/day free)
- Anthropic API - For daily summaries ($5 credit)
- ElevenLabs API - For voice summaries (10K chars/month free)
- Tavily API - For web search (1K searches/month free)
- Basic command line/terminal usage
- Ability to edit configuration files
- Understanding of environment variables
Get Logan running in 5 minutes:
# 1. Clone the repository
git clone https://github.com/hoodini/whatsapp-logger.git
cd whatsapp-logger
# 2. Install dependencies
npm install
# 3. Create environment file
cp .env.example .env
# 4. Edit .env with your API keys (use nano, vim, or any text editor)
nano .env
# 5. Build the TypeScript code
npm run build
# 6. Start the bot
npm start
# 7. Scan QR code with your bot's WhatsApp
# Open WhatsApp on the phone you want to use as the bot
# Go to: Settings > Linked Devices > Link a Device
# Scan the QR code that appears in the terminal✅ That's it! Logan is now running and will respond when mentioned in groups.
Read this if: You're new to coding, databases, or setting up bots.
What is Supabase? It's a free online database where Logan will save all WhatsApp messages.
Why do I need this? Without a database, Logan can't remember messages or create summaries.
- Go to supabase.com in your web browser
- Click the "Start your project" button (big green button)
- Sign up with your GitHub account or email
- Verify your email if asked
- After signing in, click "New Project"
- Fill in:
- Name:
logan-bot(or any name you want) - Database Password: Create a strong password (SAVE THIS!)
- Region: Choose closest to you (e.g., "US East" if you're in USA)
- Name:
- Click "Create new project"
- Wait 2-3 minutes for setup to complete
These are like keys to access your database.
- In your Supabase project, click "Settings" (gear icon on left sidebar)
- Click "API" in the settings menu
- You'll see two important things:
- Project URL: Looks like
https://abcdefgh.supabase.co - anon public key: Long text starting with
eyJ...
- Project URL: Looks like
- Copy these - you'll need them soon!
💡 Tip: Open Notepad and paste these there temporarily so you don't lose them.
What are tables? Like spreadsheets where Logan stores messages.
- In Supabase, click "SQL Editor" on the left sidebar
- Click "New Query" button
- Copy and paste this entire code block into the editor:
-- Main messages table
CREATE TABLE whatsapp_messages (
id TEXT PRIMARY KEY,
chat_id TEXT NOT NULL,
chat_name TEXT,
sender_name TEXT,
sender_number TEXT,
message_type TEXT,
body TEXT,
timestamp BIGINT NOT NULL,
from_me BOOLEAN DEFAULT FALSE,
is_group BOOLEAN DEFAULT TRUE,
is_content BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_messages_chat_id ON whatsapp_messages(chat_id);
CREATE INDEX idx_messages_timestamp ON whatsapp_messages(timestamp DESC);
CREATE INDEX idx_messages_is_content ON whatsapp_messages(is_content);
-- Auth state table (for multi-device session storage)
CREATE TABLE IF NOT EXISTS whatsapp_auth_state (
key TEXT PRIMARY KEY,
value JSONB NOT NULL,
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Broadcast guard table (prevents duplicate broadcasts)
CREATE TABLE IF NOT EXISTS broadcast_guard (
id SERIAL PRIMARY KEY,
operation_key TEXT NOT NULL,
broadcast_type TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'started',
started_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
completed_at TIMESTAMP WITH TIME ZONE,
run_id TEXT NOT NULL,
groups_sent TEXT[] DEFAULT '{}',
error_message TEXT
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_broadcast_guard_active_lock
ON broadcast_guard(operation_key) WHERE status = 'started';
CREATE INDEX IF NOT EXISTS idx_broadcast_guard_key ON broadcast_guard(operation_key);
-- Pending responses table (for failed message delivery)
CREATE TABLE IF NOT EXISTS pending_responses (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
group_id TEXT NOT NULL,
sender_number TEXT NOT NULL,
sender_name TEXT NOT NULL,
response TEXT NOT NULL,
response_type TEXT NOT NULL CHECK (response_type IN ('landing_page', 'video', 'agent')),
retry_count INTEGER DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_pending_responses_created_at
ON pending_responses(created_at ASC);- Click the "Run" button (or press F5)
- You should see "Success. No rows returned" - that's good!
What just happened? You created 4 "tables" (like 4 spreadsheets) where Logan will store:
- All WhatsApp messages
- Bot's login session
- Broadcast tracking (to prevent duplicate messages)
- Failed messages (to retry later)
What are API keys? Think of them like passwords that let Logan use AI services to respond smartly.
Why do I need multiple? Each service does something different:
- Groq: Fast AI responses when people @mention Logan
- Anthropic (Claude): Creates daily summaries
- ElevenLabs: Turns summaries into voice messages (optional)
- Tavily: Searches the web for fresh info (optional)
What it does: Makes Logan respond intelligently when mentioned in groups.
- Go to console.groq.com
- Click "Sign in with Google" (or use email)
- After login, look for "API Keys" on the left menu
- Click "Create API Key" button
- Give it a name like
logan-bot - Copy the key - it starts with
gsk_... - Paste it in your Notepad (don't lose it!)
💡 Tip: Free tier gives you 200,000 tokens/day (that's like 50,000 messages)
What it does: Creates daily summaries of group discussions.
- Go to console.anthropic.com
- Click "Get API Keys"
- Sign up with email
- Verify your email
- After login, click "Get API Keys" again
- Click "Create Key" button
- Copy the key - it starts with
sk-ant-... - Paste it in your Notepad
💰 Cost: You get $5 free credit. Daily summaries cost ~$0.01 each, so 500 summaries free!
What it does: Turns text summaries into voice messages (cool but not required).
Skip this if: You don't need voice summaries.
- Go to elevenlabs.io
- Sign up for free
- Click your profile picture → "Profile"
- Look for "API Key"
- Copy and save it
What is Node.js? The programming language runtime that runs Logan.
Do I have it already? Let's check!
Open your terminal/command prompt:
- Windows: Press
Windows + R, typecmd, press Enter - Mac: Press
Cmd + Space, typeterminal, press Enter - Linux: Press
Ctrl + Alt + T
Type this command and press Enter:
node --versionIf you see: v18.x.x or higher → Great! Skip to Step 4.
If you see: Error or version below 18 → Continue below.
- Go to nodejs.org
- Download the LTS version (left button - has "Recommended" label)
- Run the installer
- Click "Next" until it installs
- Restart your terminal
- Type
node --versionagain - should see v20.x.x or similar
Open your terminal and type these commands one by one:
# Download Logan's code
git clone https://github.com/hoodini/whatsapp-logger.git
# Enter the folder
cd whatsapp-logger
# Install required packages (takes 1-2 minutes)
npm installWhat's happening?
git clone: Downloads Logan's code to your computercd whatsapp-logger: Goes into the Logan foldernpm install: Downloads 50+ helper libraries Logan needs
If git command fails: You need to install Git first from git-scm.com
# Windows
copy .env.example .env
# Mac/Linux
cp .env.example .envWhat just happened? You created a .env file - this is where your secret keys go.
Now we'll edit the .env file with all those keys you saved earlier.
Windows: Right-click .env → Open with → Notepad
Mac: Double-click .env (opens in TextEdit)
Linux: Use nano .env or your favorite editor
Find each line and paste your keys:
Database (from Step 1.3):
SUPABASE_URL=https://abc123.supabase.co
SUPABASE_KEY=eyJ...your-long-key...AI Keys (from Step 2):
GROQ_API_KEY=gsk_...your-groq-key...
ANTHROPIC_API_KEY=sk-ant-...your-anthropic-key...
ELEVENLABS_API_KEY=...your-elevenlabs-key... # Optional - leave empty if you didn't get oneBot's Phone Number:
This is the WhatsApp number that will become the bot. Format: numbers only, no + or dashes.
BOT_PHONE_NUMBER=972501234567 # Replace with your bot's numberSecurity Key:
Generate a random password for the API:
# Windows (in PowerShell):
-join ((65..90) + (97..122) + (48..57) | Get-Random -Count 32 | % {[char]$_})
# Mac/Linux:
openssl rand -hex 32Copy the result and paste:
API_KEY=a3f9d8e2b1c4...your-random-key...Features - Leave These As-Is for Now:
DAILY_SUMMARY_ENABLED=true
DAILY_SUMMARY_TIME=22:00
SHABBAT_ENABLED=true
SPAM_DETECTION_ENABLED=true💡 Don't worry about the advanced settings yet! The defaults work fine for beginners.
- Press
Ctrl + S(Windows/Linux) orCmd + S(Mac) - Close the editor
Almost there! Now we'll turn Logan on.
In your terminal (still in the whatsapp-logger folder):
npm run buildWhat's happening? Converting TypeScript code to JavaScript (takes 10-30 seconds).
If you see errors: Make sure you filled in the .env file correctly. Check for typos!
npm startYou should see:
[INFO] Starting WhatsApp bot...
[INFO] API server listening on port 7700
[INFO] Connecting to WhatsApp...
Then a QR CODE will appear! 📱
This is the magic moment! You'll link WhatsApp to Logan.
-
Open WhatsApp on the phone that will be the bot
⚠️ Important: This phone cannot use WhatsApp normally anymore! Use a spare phone or new SIM.
-
In WhatsApp:
- Tap the three dots (⋮) in top right
- Tap "Linked Devices"
- Tap "Link a Device"
-
Scan the QR code from your computer screen
-
Wait 5-10 seconds...
Success! You should see:
[INFO] WhatsApp connection established
[INFO] Bot JID: 972501234567@s.whatsapp.net
🎉 Logan is alive!
Let's make sure everything works!
- Create a new WhatsApp group (or use an existing one)
- Add your bot's number to the group
- Important: Make the bot an admin!
- Tap group name
- Scroll to bot's number
- Long press → Make group admin
In the group, send this message:
@Logan hello! are you working?
Logan should reply within a few seconds! 🎉
If it doesn't reply:
- Check the terminal for errors
- Make sure you @mentioned the exact name saved in your contacts
- Check that
BOT_PHONE_NUMBERin.envmatches exactly (no + or -)
Logan is running! But only while your terminal is open. Here's what to do:
For beginners: Just leave your computer and terminal open.
For advanced users: Set up PM2 (see Production Deployment section below).
Want more features? Edit your .env file:
Shabbat Auto-Lock (for Jewish users):
SHABBAT_ENABLED=true
SHABBAT_LOCK_LOCATION=281184 # JerusalemFind your city: geonames.org
Daily Summaries: Already enabled! Logan will send a summary at 22:00 Israel time daily.
Web Search (optional): Get a free key at tavily.com and add:
TAVILY_API_KEY=tvly-...your-key...- Check
BOT_PHONE_NUMBERin.envmatches your number exactly - The contact name must match what you @mentioned
- Try restarting: Press
Ctrl+Cin terminal, thennpm startagain
- Check your internet connection
- Make sure port 7700 isn't already in use
- Try deleting the
auth_infofolder and runningnpm startagain
- Check
SUPABASE_URLandSUPABASE_KEYare correct - Make sure you ran the SQL from Step 1.4
- Check Supabase dashboard - project might be paused
- Double-check the keys in
.env- no extra spaces! - Make sure keys start with correct prefix:
- Groq:
gsk_ - Anthropic:
sk-ant-
- Groq:
- Test keys at their respective console websites
Still stuck? Open an issue on GitHub with:
- What step failed
- The error message (remove your keys!)
- Your OS (Windows/Mac/Linux)
Only read this after you have Logan working!
- Jerusalem: 281184
- Tel Aviv: 293397
- Haifa: 294801
- Search for other cities at geonames.org
# Build TypeScript to JavaScript
npm run build
# Start the bot
npm startYou should see:
[INFO] Starting WhatsApp bot...
[INFO] API server listening on port 7700
[INFO] Connecting to WhatsApp...
A QR code will appear in your terminal.
- Open WhatsApp on the phone you want to use as the bot
- Go to Settings (⚙️)
- Tap Linked Devices
- Tap Link a Device
- Scan the QR code from the terminal
✅ Success! You should see:
[INFO] WhatsApp connection established
[INFO] Bot JID: 972501234567@s.whatsapp.net
- Add the bot's WhatsApp number to any group
- Make the bot an admin (required for locking/unlocking and spam removal)
- Tap group name > Participants
- Find bot's number
- Long press > "Make group admin"
Send a message in the group:
@Logan שלום! מה שלומך?
The bot should respond with an AI-generated reply!
Test other features:
# Test daily summary
curl -X POST http://localhost:7700/api/summary/trigger \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"groupId": "120363..."}'
# Check health
curl http://localhost:7700/api/health \
-H "x-api-key: your-api-key"
# List groups
curl http://localhost:7700/api/groups \
-H "x-api-key: your-api-key"See .env.example for complete documentation of all settings.
| Variable | Required | Default | Description |
|---|---|---|---|
SUPABASE_URL |
✅ Yes | - | Your Supabase project URL |
SUPABASE_KEY |
✅ Yes | - | Supabase anon/public key |
GROQ_API_KEY |
✅ Yes | - | Groq API for AI responses |
ANTHROPIC_API_KEY |
✅ Yes | - | Claude API for summaries |
BOT_PHONE_NUMBER |
✅ Yes | - | Bot's WhatsApp number (format: 972501234567) |
API_KEY |
- | API authentication key | |
API_PORT |
No | 7700 | API server port |
ELEVENLABS_API_KEY |
No | - | For voice summaries |
DAILY_SUMMARY_ENABLED |
No | true | Enable daily summaries |
DAILY_SUMMARY_TIME |
No | 22:00 | Summary time (24h, Israel TZ) |
SHABBAT_ENABLED |
No | true | Enable Shabbat auto-lock |
SHABBAT_LOCK_OFFSET |
No | -30 | Minutes before candle lighting |
SHABBAT_UNLOCK_OFFSET |
No | 30 | Minutes after havdalah |
SPAM_DETECTION_ENABLED |
No | true | Enable spam detection |
SPAM_WHITELIST |
No | - | Comma-separated exempt numbers |
AUTO_PROCESS_JOIN_REQUESTS |
No | true | Auto-approve/reject join requests |
JOIN_REQUEST_BOT_THRESHOLD |
No | 3 | Bot suspicion score threshold (0-5) |
MAX_GROUP_SIZE |
No | 1024 | Maximum group members |
ALLOWED_GROUPS |
No | - | JSON array of groups to monitor (empty = all groups) |
AGENT_ADMIN_NUMBERS |
No | - | Comma-separated admin phone numbers |
ADMIN_ONLY_MODE |
No | false | Restrict bot to admins only |
TAVILY_API_KEY |
No | - | For web search integration |
LOG_LEVEL |
No | info | Logging level (info/debug/warn/error) |
By default, Logan monitors ALL groups it's added to. To restrict to specific groups:
# Monitor only these groups (JSON array)
ALLOWED_GROUPS='[
{"id":"120363XXXXXXXXXX@g.us","name":"My Group 1"},
{"id":"120363YYYYYYYYYY@g.us","name":"My Group 2"}
]'To get a group ID:
curl http://localhost:7700/api/groups -H "x-api-key: your-key"Control who can use advanced features (agent, web search, tools):
# Admins can use all features in any group or DM
AGENT_ADMIN_NUMBERS=972501234567,972509876543
# Groups where ALL users can use advanced features
AGENT_PUBLIC_GROUPS=120363XXXXXXXXXX@g.us
# Groups where ALL users can chat with Logan (text only, no tools)
AGENT_FREE_CHAT_GROUPS=120363XXXXXXXXXX@g.usRestrict Logan to admin-only usage:
ADMIN_ONLY_MODE=true
AGENT_ADMIN_NUMBERS=972501234567When enabled:
- Only users in
AGENT_ADMIN_NUMBERScan interact with Logan - Bot ignores all other users in groups and DMs
- Useful for testing or private bot instances
Most users should skip this - it's an advanced feature requiring separate setup.
Copilot SDK Agent integration enables:
- Video generation with Remotion
- MCP server access (Obsidian, Tavily, Atlassian)
- Shell command execution
COPILOT_AGENT_ENABLED=false # Keep disabled unless you know what this is
COPILOT_AGENT_URL=http://localhost:4001
COPILOT_AGENT_PUBLIC_PATH=/path/to/agent/publicSee ADVANCED.md for Copilot setup (advanced users only).
Before deploying:
- Never commit
.env- Contains all your API keys - Never commit
auth_info/- Anyone with this can impersonate your bot - Set strong
API_KEY- Generate withopenssl rand -hex 32 - Enable Supabase RLS - Protect your database with Row Level Security
- Run
npm audit- Check for vulnerable dependencies - Use HTTPS - If exposing API publicly
- Rotate keys regularly - Especially if leaked
| File/Folder | Contains | Risk if Leaked |
|---|---|---|
.env |
All API keys, database credentials | Full bot takeover, API abuse charges |
auth_info/ |
WhatsApp session | Anyone can impersonate your bot |
shabbat_lock_state.json |
Lock state (safe) | None - just local state |
shabbat_times_cache.json |
Cached Shabbat times (safe) | None - just cached data |
Protect your database with RLS policies:
-- Enable RLS
ALTER TABLE whatsapp_messages ENABLE ROW LEVEL SECURITY;
ALTER TABLE whatsapp_auth_state ENABLE ROW LEVEL SECURITY;
ALTER TABLE broadcast_guard ENABLE ROW LEVEL SECURITY;
ALTER TABLE pending_responses ENABLE ROW LEVEL SECURITY;
-- Allow authenticated access
CREATE POLICY "Authenticated users can read messages"
ON whatsapp_messages FOR SELECT
USING (auth.role() = 'authenticated');
CREATE POLICY "Service role full access"
ON whatsapp_messages FOR ALL
USING (auth.role() = 'service_role');📖 See SECURITY.md for complete security guidelines, including:
- Incident response procedures
- API key rotation
- GDPR/privacy compliance
- Secure deployment practices
All endpoints require x-api-key header when API_KEY is configured.
# Health check
GET /api/health
Response: { "status": "ok", "connected": true, "timestamp": "..." }
# List monitored groups
GET /api/groups
Response: [{ "id": "120363...", "name": "My Group", "participants": 25 }]
# View message queue
GET /api/queue
Response: { "pending": 3, "processing": 0 }# Send message to specific group
POST /api/send-message
Body: {
"groupId": "120363012345678901@g.us",
"message": "Hello everyone!",
"mentionNumber": "972501234567" # Optional
}
# Broadcast to all groups
POST /api/broadcast
Body: { "message": "Important announcement!" }# Trigger immediate summary for a group
POST /api/summary/trigger
Body: { "groupId": "120363012345678901@g.us" }
# Test summary generation (dry run)
GET /api/summary/test/:groupId# Lock all groups (testing)
GET /api/test-shabbat-lock
# Unlock all groups (testing)
GET /api/test-shabbat-unlock
# Lock specific group
POST /api/group-lock
Body: { "groupId": "120363..." }
# Unlock specific group
POST /api/group-unlock
Body: { "groupId": "120363..." }# View whitelist
GET /api/spam/whitelist
# Add number to whitelist
POST /api/spam/whitelist
Body: { "number": "972501234567" }📖 Full API documentation: See source code in src/api.ts
┌─────────────────────────────────────────────────────────────────┐
│ LOGAN BOT │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────────┐ │
│ │ WhatsApp │────▶│ Message │────▶│ Supabase │ │
│ │ (Baileys) │ │ Handler │ │ (Storage) │ │
│ └──────────────┘ └──────┬───────┘ └────────────────┘ │
│ │ │
│ ┌────────────────────┼────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────────┐ │
│ │ Mention │ │ Voice │ │ Spam │ │
│ │ Response │ │ Transcribe│ │ Detection │ │
│ │ (Groq) │ │ (Whisper) │ │ (Groq) │ │
│ └────────────┘ └────────────┘ └────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Scheduled Tasks │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
│ │ │ Daily │ │ Shabbat │ │ Erev Shabbat │ │ │
│ │ │ Summary │ │ Locker │ │ Summary │ │ │
│ │ │ (22:00 IL) │ │ (Hebcal) │ │ (30 min before) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Express API │ │
│ │ /api/health /api/send-message /api/broadcast ... │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
External Services:
┌──────────┐ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌────────┐
│ Groq │ │ Claude │ │ ElevenLabs│ │ Hebcal │ │ Tavily │
│ (Chat) │ │(Summary) │ │ (TTS) │ │ (Times) │ │(Search)│
└──────────┘ └──────────┘ └───────────┘ └──────────┘ └────────┘
whatsapp-logger/
├── src/
│ ├── index.ts # Entry point, initializes all services
│ ├── api.ts # Express API server
│ ├── connection.ts # WhatsApp connection management
│ ├── messageHandler.ts # Message processing pipeline
│ ├── mentionWebhook.ts # Mention detection & AI response
│ ├── supabase.ts # Database operations
│ ├── shabbatLocker.ts # Shabbat auto-lock/unlock (4-layer detection)
│ ├── broadcastGuard.ts # Supabase-backed duplicate prevention
│ ├── spamDetector.ts # Spam detection & removal
│ ├── joinRequestProcessor.ts # Auto-approve/reject join requests
│ ├── config.ts # Configuration management
│ ├── types.ts # TypeScript type definitions
│ ├── services/
│ │ ├── groq.ts # Groq API client
│ │ ├── claude.ts # Claude API client
│ │ ├── tavily.ts # Web search with source validation
│ │ ├── whisper.ts # Voice transcription
│ │ ├── elevenlabs.ts # Text-to-speech
│ │ └── supabase-auth-state.ts # Database-backed auth state
│ ├── features/
│ │ ├── daily-summary.ts # Daily summary generation & scheduling
│ │ ├── mention-response.ts # AI mention responses & voice generation
│ │ └── broadcast.ts # Group broadcast messaging
│ ├── utils/
│ │ └── botDetection.ts # Bot detection for join requests
│ └── scripts/
│ └── shavua-tov.ts # Manual Shavua Tov broadcast script
├── migrations/ # SQL migrations for Supabase
│ ├── 001_create_broadcast_guard.sql
│ ├── 002_add_atomic_lock_index.sql
│ └── 003_create_pending_responses.sql
├── docs/
│ ├── onboarding.md # Complete setup guide
│ ├── phone-change.md # Phone number change guide
│ └── SHABBAT_LOCKER.md # Shabbat lock system documentation
├── auth_info/ # WhatsApp session (gitignored!)
├── .env.example # Environment template
├── .env # Your config (gitignored!)
├── package.json
├── tsconfig.json
├── LICENSE
├── SECURITY.md # Security guidelines
└── PRE_OPEN_SOURCE_CHECKLIST.md # Open-source preparation
| Component | Purpose | Tech Stack |
|---|---|---|
| Baileys | WhatsApp Web API | WebSocket connection to WhatsApp |
| Supabase | Database & auth state | PostgreSQL with real-time |
| Groq | AI responses & spam detection | LLaMA 3.3 70B / GPT-4 class |
| Claude | Daily summaries | Claude 3.5 Sonnet |
| Whisper | Voice transcription | Groq's Whisper endpoint |
| ElevenLabs | Voice synthesis | Neural TTS |
| Hebcal | Shabbat times | Jewish calendar API |
| Tavily | Web search | Real-time search with citations |
Symptoms: Bot ignores @mentions in groups
Solutions:
- Verify
BOT_PHONE_NUMBERin.envmatches your number exactly (format: 972501234567, no + or dashes) - Check logs for "Bot JID" - should match your number
- Ensure bot is actually in the group
- Try @mentioning with the exact contact name saved in your phone
Symptoms: No summary at scheduled time
Solutions:
- Check
DAILY_SUMMARY_ENABLED=truein.env - Verify
ANTHROPIC_API_KEYis valid (test at console.anthropic.com) - Check bot logs at scheduled time (default 22:00 Israel time)
- Test manually:
curl -X POST http://localhost:7700/api/summary/trigger -H "x-api-key: your-key" - Ensure bot has sent at least a few messages in the group (needs context)
Symptoms: Groups not locking before Shabbat
Solutions:
- Verify
SHABBAT_ENABLED=truein.env - Bot MUST be admin in the group (required to change settings)
- Check
SHABBAT_LOCK_LOCATIONis set to correct geonameid - Test manually:
curl http://localhost:7700/api/test-shabbat-lock -H "x-api-key: your-key" - Check logs for "Shabbat lock" messages
Symptoms: Bot keeps disconnecting, shows "Session replaced" or error 440
Solutions:
- Close ALL other WhatsApp Web sessions - Most common cause!
- Open WhatsApp on phone > Linked Devices
- Log out all other sessions
- Check for duplicate bot instances running:
# Windows tasklist | findstr node # Kill extra instances # Linux/Mac ps aux | grep node kill <pid>
- Delete
auth_info/and re-scan QR code (fresh session) - Wait 5-10 minutes if rate limited (bot uses exponential backoff)
- Ensure stable internet connection
Symptoms: Voice messages don't get transcribed
Solutions:
- Check
GROQ_API_KEYis valid - Verify Groq daily quota (200K tokens/day on free tier)
- Check logs for "Whisper" errors
- Voice file might be corrupted - ask sender to resend
Symptoms: Legitimate users getting flagged as spam
Solutions:
- Add them to whitelist:
SPAM_WHITELIST=972501234567,972509876543 - Review spam logs to understand why they were flagged
- Adjust spam detection prompt in
src/spamDetector.tsif needed - Temporarily disable:
SPAM_DETECTION_ENABLED=false
Symptoms: Errors about Supabase or database connection
Solutions:
- Verify
SUPABASE_URLandSUPABASE_KEYare correct - Check Supabase dashboard - project might be paused (free tier after 1 week inactivity)
- Run migrations if tables don't exist (see Setup Step 1)
- Check Supabase logs in dashboard for specific errors
Symptoms: 401 Unauthorized errors from APIs
Solutions:
- Verify each API key in respective console:
- Groq: console.groq.com
- Anthropic: console.anthropic.com
- ElevenLabs: elevenlabs.io
- Check for extra spaces in
.envfile - Ensure keys haven't expired or been revoked
- Regenerate keys if needed
Symptoms: Bot using too much RAM or CPU
Solutions:
- Increase Node.js memory limit:
node --max-old-space-size=4096 dist/index.js
- Reduce context window: Lower message history limits in code
- Clear old messages from database periodically
- Monitor with
pm2 monitif using PM2
Symptoms: Need group ID for API calls
Solutions:
# List all groups with IDs
curl http://localhost:7700/api/groups -H "x-api-key: your-key"
# Or check logs when bot receives a message - group ID is loggedPM2 keeps your bot running 24/7 with auto-restart on crashes:
# Install PM2 globally
npm install -g pm2
# Build the project
npm run build
# Start with PM2
pm2 start dist/index.js --name logan
# Save PM2 config
pm2 save
# Enable auto-start on system boot
pm2 startup
# Follow the instructions printed
# Monitor
pm2 monit # Real-time monitoring
pm2 logs logan # View logs
pm2 restart logan # Restart bot
pm2 stop logan # Stop bot# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]# Build and run
docker build -t logan-bot .
docker run -d \
--name logan \
--env-file .env \
-v $(pwd)/auth_info:/app/auth_info \
-p 7700:7700 \
logan-bot# Health check endpoint
curl http://localhost:7700/api/health
# Check logs
pm2 logs logan
# Check system resources
pm2 monit
# Restart if needed
pm2 restart logan- Onboarding Guide - Complete step-by-step setup
- Phone Change Guide - How to change bot's WhatsApp number
- Shabbat Lock System - Technical details of Shabbat protection
- Security Guidelines - Security best practices & incident response
- Open Source Prep - Checklist before going public
- Environment Variables - Complete configuration reference
Contributions are welcome! Here's how:
- Check existing issues first
- Provide:
- Logan version (
package.json) - Node.js version (
node --version) - Error logs (redact sensitive info!)
- Steps to reproduce
- Logan version (
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature - Make changes and test thoroughly
- Commit with clear messages:
git commit -m "feat: Add voice summary cooldown" git commit -m "fix: Handle 440 errors with exponential backoff"
- Push and create a Pull Request
# Clone your fork
git clone https://github.com/yourusername/whatsapp-logger.git
# Install dependencies
npm install
# Run in development mode (hot reload)
npm run dev
# Run tests (if available)
npm test
# Build for production
npm run build- Use TypeScript for all new code
- Follow existing code style
- Add comments for complex logic
- Update documentation if changing behavior
MIT License - see LICENSE file for details.
Copyright (c) 2024-2026 Yuval Avidani (@hoodini)
This means you can:
- ✅ Use commercially
- ✅ Modify
- ✅ Distribute
- ✅ Private use
You must:
- 📝 Include license and copyright notice
- 📝 State changes made
- 📝 Attribute to original author
Yuval Avidani - AI Speaker & Builder
Connect with me:
- 🌐 Website: yuv.ai
- 🐙 GitHub: @hoodini
- 🐦 Twitter/X: @yuvalav
- 📸 Instagram: @yuval_770
- 🎥 YouTube: @yuv-ai
- 🔗 Linktree: linktr.ee/yuvai
About: Yuval is a 2x GitHub Star and 2x AWS Gen AI Superstar, passionate about building AI-powered tools for communities. Logan is a passion project built with love and released to the open-source community to help others create intelligent WhatsApp bots.
"Building AI tools that make a real difference in people's daily lives." - Yuval Avidani
Built with these amazing open-source projects:
- Baileys - WhatsApp Web API by @WhiskeySockets
- Supabase - Open source Firebase alternative
- Anthropic Claude - Advanced AI for daily summaries
- Groq - Lightning-fast LLM inference
- ElevenLabs - Realistic voice synthesis
- Hebcal - Jewish calendar API
- Tavily - AI-optimized search API
- Node.js - JavaScript runtime
- TypeScript - Type-safe JavaScript
- Express - Web framework
- Pino - Fast logging
- The Israeli tech community for inspiration and feedback
- Early testers who helped refine Logan's features
- The open-source community for making projects like this possible
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Security: See SECURITY.md for reporting vulnerabilities
- Questions: Open a discussion or reach out to @hoodini
Contributions are welcome! See Contributing section above for guidelines.
If Logan helped you, consider:
- ⭐ Starring this repo
- 🐛 Reporting bugs
- 💡 Suggesting features
- 📝 Improving documentation
- 🔧 Submitting pull requests
This is an unofficial, community-maintained project not affiliated with or endorsed by WhatsApp, Meta, Facebook, or any official Logan project. Use at your own risk.
Important:
- Using WhatsApp bots may violate WhatsApp's Terms of Service
- Your account could be banned if detected
- This software is provided "as is" without warranty
- The author is not responsible for any consequences of using this software
Privacy Notice:
- This bot logs all messages from groups it's added to
- Ensure compliance with local privacy laws (GDPR, CCPA, etc.)
- Inform group members about logging
- Provide opt-out mechanisms if required by law
- You are responsible for data protection and privacy compliance
Ethical Use:
- Only use Logan in groups where all members are aware and consent
- Respect privacy and data protection laws
- Do not use for spam, harassment, or malicious purposes
- Be transparent about bot presence and capabilities
Built with ❤️ for the open source community by Yuval Avidani
🌐 Website • 🐙 GitHub • 🐦 Twitter • 🎥 YouTube
If Logan helped you, consider starring ⭐ this repo and sharing it with others!