AI-Powered WhatsApp Automation with Event-Driven Smart Handlers
A production-ready Go application that transforms WhatsApp into a full-featured AI automation platform. Built on the whatsmeow library and the Model Context Protocol (MCP), this tool enables AI agents to send/receive messages, manage groups, handle media, and create sophisticated event-driven automation workflows.
Key Innovation: Event handlers can trigger Python scripts, call LLMs, query databases, control hardware, browse the web, and orchestrate unlimited automation using the entire MCP tool ecosystemβall while maintaining safety through rate limiting, circuit breakers, and concurrent execution.
- β Send/Receive Messages - Text, images, videos, audio, documents, stickers
- β Generic Dispatcher - Call ANY whatsmeow method without custom code
- β Query Message History - Filter by sender, chat, time, type
- β Event-Driven Automation - Python handlers triggered by WhatsApp events
- β Multi-Modal QR Code - ASCII art, Base64 image, beautiful HTML popup
- β Auto-Login - Session persistence with automatic reconnection
- β Panic Recovery - 2-layer crash protection, server stays running
- β Comprehensive Error Handling - Detailed logs, health monitoring, AI inspection
Program WhatsApp to respond to events using Python, LLMs, databases, and more:
# Handler receives WhatsApp message
# Queries database for context
# Calls LLM for smart response
# Returns actions to execute
return {
'actions': [
{'type': 'send_chat_presence', 'jid': '...', 'state': 'composing'},
{'type': 'delay', 'seconds': 1.5},
{'type': 'send_message', 'to': '...', 'message': {'conversation': 'AI reply'}},
{'type': 'mark_read', 'chat': '...', 'message_ids': ['...']}
]
}Handlers can:
- π Execute Python code with full MCP tool access
- π§ Call 500+ AI models via OpenRouter
- ποΈ Query/update SQLite databases
- π Automate Chrome browser
- π₯οΈ Control desktop applications
- π± Trigger hardware via serial/SSH
- π¬ Show HTML popups to users
- π Chain multiple actions with variable substitution
- Rate Limiting - Per-minute, per-hour, per-sender limits
- Circuit Breakers - Auto-disable failing handlers
- Loop Prevention - Filter own messages, cooldowns, execution tracking
- Concurrent Execution - Non-blocking goroutines, main loop stays responsive
- Timeout Protection - Configurable handler timeouts (default 30s)
- Execution Logging - Complete audit trail in SQLite
-
MCP-Link Server
Download from: https://github.com/AuraFriday/mcp-link-server/releases/latest -
Go 1.24+ (for building from source)
Install from: https://go.dev/dl/
# Clone this repository
git clone https://github.com/yourusername/whatsmeow.git
cd whatsmeow
# Build the tool
make
# Run the tool (connects to MCP server automatically)
./whatsapp_mcp.exeThe tool auto-discovers the MCP server via native messaging manifest and registers itself as the whatsapp tool.
Get QR code for pairing:
{
"operation": "get_qr_code"
}Displays QR code in:
- β Terminal (ASCII art)
- β IDE (Base64 image)
- β Desktop popup (HTML window)
Scan with WhatsApp mobile app β Instant connection!
{
"operation": "call_whatsmeow",
"data": {
"method": "SendMessage",
"params": {
"to": "61487543210",
"message": {"conversation": "Hello from AI! π€"}
}
}
}Phone numbers auto-format: "61487543210" β "61487543210@s.whatsapp.net"
{
"operation": "get_messages",
"data": {
"limit": 50,
"from": "61487543210@s.whatsapp.net",
"since": "2025-11-10T00:00:00Z"
}
}{
"operation": "register_handler",
"data": {
"handler_id": "auto_reply",
"description": "Responds to hello messages",
"event_filter": {
"event_types": ["message"],
"is_from_me": false,
"text_contains": ["hello", "hi"]
},
"action": {
"type": "python",
"code": "return {'actions': [{'type': 'send_message', 'to': event['from'], 'message': {'conversation': 'Hello! How can I help?'}}]}"
},
"enabled": true,
"max_executions_per_hour": 50,
"timeout_seconds": 30
}
}Now every "hello" message triggers your handler automatically!
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AI Agent (Claude, GPT, etc.) β
β Programs handlers via natural language β JSON β
ββββββββββ¬βββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββ
β β
β Register Handlers β Query/Control
βΌ βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β WhatsApp MCP Tool (Go) β
β β
β ββββββββββββββββ βββββββββββββββββ βββββββββββββββββββ β
β β Handler β β Event β β Action β β
β β Registry ββββ Processor βββΆβ Executor β β
β β (SQLite) β β (Goroutines) β β (Python) β β
β ββββββββββββββββ βββββββββββββββββ βββββββββββββββββββ β
β β β β
β βΌ βΌ β
β βββββββββββββββ βββββββββββββββ β
β β whatsmeow β β MCP Tools β β
β β Client β β Ecosystem β β
β βββββββββββββββ βββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
βΌ βΌ
WhatsApp Servers Python, SQLite,
OpenRouter, Browser,
User, System, etc.
1. WhatsApp message arrives
β
2. Saved to database
β
3. Event matcher finds handlers (filters, rate limits, circuit breakers)
β
4. Spawn handler goroutines (NON-BLOCKING!)
β
5. Download media if present
β
6. Execute Python handler
βββ Handler can call WhatsApp for research (GetUserInfo, etc.)
β βββ Main loop responds (still running!)
βββ Handler returns actions
β
7. Execute actions (send_message, mark_read, delay, etc.)
β
8. Log execution, update stats
β
9. Clean up temp files
Main event loop NEVER blocks - handlers run concurrently in goroutines!
# Handler code
# Get conversation history from database
history = mcp.call('sqlite', {
'input': {
'sql': 'SELECT * FROM messages WHERE from_jid = :jid LIMIT 10',
'bindings': {'jid': event['from']},
'database': '@user_data/conversations.db'
}
})
# Analyze with LLM
response = mcp.call('openrouter', {
'input': {
'operation': 'chat_completion',
'model': 'anthropic/claude-3.5-sonnet',
'messages': [
{'role': 'system', 'content': 'You are a helpful customer service agent.'},
{'role': 'user', 'content': f'History: {history}\nNew: {event["text_content"]}'}
]
}
})
# Return actions
return {
'actions': [
{'type': 'send_chat_presence', 'jid': event['from'], 'state': 'composing'},
{'type': 'delay', 'seconds': 2.0},
{'type': 'send_message', 'to': event['from'],
'message': {'conversation': response['content'][0]['text']}},
{'type': 'mark_read', 'chat': event['chat'], 'message_ids': [event['message_id']]}
]
}# Handler automatically receives downloaded media
if event.get('has_media'):
media_path = event['media_path'] # /tmp/whatsapp_media/3EB0ABC123_image.jpg
# Process media
from PIL import Image
img = Image.open(media_path)
# Archive it
import shutil
archive_path = f"/archive/{event['sender_name']}_{event['message_id']}.jpg"
shutil.copy(media_path, archive_path)
# Log to database
mcp.call('sqlite', {
'input': {
'sql': 'INSERT INTO media_archive (path, from_jid, size) VALUES (?, ?, ?)',
'params': [archive_path, event['from'], event['media_size']],
'database': '@user_data/media.db'
}
})
return {
'actions': [
{'type': 'send_message', 'to': event['from'],
'message': {'conversation': f'Media archived: {archive_path}'}}
]
}# Handler for owner only
if event['from'] == '61414505452@s.whatsapp.net':
text = event['text_content'].lower()
if 'turn on' in text or 'turn off' in text:
# Send command to hardware via serial
mcp.call('mcu_serial', {
'input': {
'operation': 'send',
'port': 'COM5',
'data': f'{text.upper()}\n'
}
})
return {
'actions': [
{'type': 'send_message', 'to': event['from'],
'message': {'conversation': f'Command sent: {text}'}}
]
}# Analyze message with LLM for toxicity
analysis = mcp.call('openrouter', {
'input': {
'operation': 'chat_completion',
'model': 'anthropic/claude-3.5-sonnet',
'messages': [
{'role': 'system', 'content': 'Analyze if appropriate. Return JSON: {"appropriate": true/false, "reason": "..."}'},
{'role': 'user', 'content': event['text_content']}
]
}
})
import json
result = json.loads(analysis['content'][0]['text'])
if not result['appropriate']:
return {
'actions': [
# Delete message
{'type': 'call_method', 'method': 'BuildRevoke',
'params': {'chat': event['chat'], 'message_id': event['message_id']}},
# Warn user privately
{'type': 'send_message', 'to': event['from'],
'message': {'conversation': f'Message removed: {result["reason"]}'}}
]
}check_login_status- Check connection statusget_qr_code- Get QR code for pairing (multi-modal)logout- Disconnect and clear sessionget_connection_info- Detailed connection info
call_whatsmeow- Generic dispatcher (call ANY whatsmeow method)get_messages- Query message history with filtersget_method_registry- Get full method list with examples
register_handler- Create event handlerlist_handlers- List all handlersget_handler- Get specific handler detailsupdate_handler- Update handler configurationdelete_handler- Remove handlerenable_handler/disable_handler- Toggle handlerget_handler_executions- Query execution logsreload_handlers- Reload from database
get_version- Tool version and PIDget_health_status- System health checkget_error_log- Recent errorsclear_error_state- Clear non-critical errorsget_config/set_config- Configuration managementshutdown- Graceful shutdown
- SendMessage - Send text/media messages
- SendPresence - Set online/offline status
- SendChatPresence - Typing/recording indicators
- GetUserInfo - Get user profile information
- GetProfilePictureInfo - Get profile pictures
- MarkRead - Mark messages as read
- BuildEdit - Edit sent messages
- BuildRevoke - Delete/revoke messages
- DownloadMediaWithPath - Download media files
More methods coming soon: Groups, contacts, reactions, polls, locations, and more!
CORRECT:
# Handler returns what to do
return {
'actions': [
{'type': 'send_message', 'to': event['from'], 'message': {...}}
]
}WRONG:
# Don't call WhatsApp directly from handler
mcp.call('whatsapp', {'operation': 'call_whatsmeow', ...})Exception: Research queries (READ operations) are OK:
# This is fine - querying WhatsApp state
user_info = mcp.call('whatsapp', {
'input': {'operation': 'call_whatsmeow', 'method': 'GetUserInfo', ...}
})Use Python's tempfile module:
import tempfile
temp_dir = tempfile.mkdtemp(prefix='whatsapp_')
# OS cleans up on rebootMedia is pre-downloaded:
if event.get('has_media'):
media_path = event['media_path']
# Process it - Go cleans up after handler completesSave complex logic to files:
# Use Python tool's save_script feature
mcp.call('python', {
'input': {
'operation': 'save_script',
'filename': 'my_handler.py',
'code': '...'
}
})
# Stored in: @user_data/python_scripts/Always configure limits:
{
"limits": {
"max_executions_per_minute": 10,
"max_executions_per_hour": 100,
"max_executions_per_sender_per_hour": 5,
"cooldown_seconds": 60,
"timeout_seconds": 30
},
"circuit_breaker": {
"enabled": true,
"failure_threshold": 5,
"reset_timeout_seconds": 300
}
}Critical filters:
- Always use
"is_from_me": falseto prevent responding to own messages - Set reasonable rate limits
- Configure cooldowns between executions
These tools ship with MCP-Link and work immediately:
| Tool | Description |
|---|---|
| π Python | Execute code locally with full MCP tool access |
| π§ SQLite | Database with semantic search and embeddings |
| π Browser | Automate Chrome: read, click, type, navigate |
| π€ OpenRouter | Access 500+ AI models (free and paid) |
| π€ HuggingFace | Run AI models offline (no internet needed) |
| π Context7 | Pull live documentation for any library |
| π₯οΈ Desktop | Control Windows apps (click, type, read) |
| π¬ User | Show HTML popups for forms, confirmations |
| π Remote | Let external systems offer tools (like this one!) |
Want more? Add any third-party MCP tools or build your own!
- Go 1.24+ - Fast, concurrent, reliable
- whatsmeow - WhatsApp Web multidevice API
- SQLite - Session storage, handler registry, message history
- MCP Protocol - Tool registration and communication
- Server-Sent Events (SSE) - Real-time event streaming
- JSON-RPC - Command execution protocol
- Zero overhead on WhatsApp connection
- Non-blocking architecture - goroutines for concurrency
- Panic recovery - 2-layer crash protection
- Auto-reconnect - Exponential backoff for transient errors
- Efficient media handling - Temp files, automatic cleanup
- Session encryption - SQLite database with secure storage
- Rate limiting - Multiple layers of protection
- Loop prevention - Filter own messages, cooldowns, execution tracking
- Circuit breakers - Auto-disable failing handlers
- Execution logging - Complete audit trail
| File | Purpose |
|---|---|
README.md |
This file - overview and quick start |
reverse_mcp_dev_plans.md |
Complete development plan and roadmap |
EVENT_DRIVEN_ARCHITECTURE.md |
Event system architecture and examples |
HANDLER_BEST_PRACTICES.md |
Best practices for programming handlers |
TOOL_DOCUMENTATION_FOR_LLMS.md |
Complete API reference for AI agents |
ARCHITECTURE_SUMMARY.md |
Quick reference guide |
- Authentication (QR code, auto-login, session persistence)
- Send/receive messages (text, media, documents)
- Generic dispatcher (call ANY whatsmeow method)
- Query message history
- Event handler storage (SQLite)
- Event matching engine (11 filter types)
- Action executor (Python + 7 action types)
- Concurrent execution model
- Media handling (download, process, cleanup)
- Safety features (rate limits, circuit breakers, loop prevention)
- Comprehensive error handling
- Panic recovery
- Execution logging
- More whatsmeow methods (groups, contacts, reactions)
- More action types (reactions, edits, forwards)
- More event types (presence, receipts, group changes)
- Handler templates (pre-built common handlers)
- Testing framework (automated handler testing)
- Performance metrics (execution time analytics)
Want to contribute? PRs welcome! This is the future of AI-powered messaging automation.
- Add more whatsmeow methods to
method_registry.json - Create example handlers for common use cases
- Improve error messages and logging
- Write integration tests
- Create tutorial videos
- Build handler templates
Proprietary - See LICENSE file for details
Created by AuraFriday
Part of the MCP-Link ecosystem
- MCP-Link Server: https://github.com/AuraFriday/mcp-link-server
- Model Context Protocol: https://modelcontextprotocol.io
- whatsmeow Library: https://github.com/tulir/whatsmeow
- Fusion 360 MCP Tool: https://github.com/AuraFriday/Fusion-360-MCP-Server (similar project)
Q: Does this work with my existing WhatsApp account?
A: Yes! Scan the QR code with your WhatsApp mobile app to link.
Q: Can I run multiple handlers simultaneously?
A: Yes! Handlers run concurrently in goroutines. Main loop stays responsive.
Q: How do I prevent infinite loops?
A: Use "is_from_me": false filter, configure rate limits, and set cooldowns.
Q: Can handlers call other MCP tools?
A: Yes! Python handlers have full access to all MCP tools (SQLite, OpenRouter, Browser, etc.)
Q: Does this work offline?
A: WhatsApp requires internet, but you can use local AI models (HuggingFace tool) for processing.
Q: Is this production-ready?
A: Yes! Includes panic recovery, error handling, rate limiting, circuit breakers, and execution logging.
Q: Can I use this with Claude/ChatGPT/etc?
A: Yes! Works with any AI that supports MCP protocol.
If you find this useful, please star the repository and share with the WhatsApp automation community!
Questions? Open an issue or check the documentation
This is the future of AI-powered WhatsApp automation. π