Parth Modi
|
dd105fd556
|
Production-grade WhatsApp refactoring with Baileys delivery fixes (#66)
* refactor(whatsapp): production-grade modular architecture + delivery fixes
Major refactoring of WhatsApp integration following OpenClaw's battle-tested
patterns. Implements proper separation of concerns, full type safety, and fixes
critical Baileys delivery issues.
Refactored monolithic 882-line file into modular structure:
New structure (14 files, 2,722 lines):
- src/channels/whatsapp/
- index.ts (750 lines) - Main orchestration
- session.ts (289 lines) - Socket creation
- types.ts (110 lines) - Type definitions
- utils.ts (171 lines) - Helper functions
- outbound.ts (181 lines) - Message sending
- inbound/
- types.ts (106 lines) - Message types
- extract.ts (173 lines) - Message parsing
- access-control.ts (189 lines) - Pairing logic
Shared utilities (reusable across channels):
- src/utils/backoff.ts (155 lines) - Reconnection primitives
- src/utils/dedupe-cache.ts (184 lines) - TTL deduplication
- src/utils/creds-queue.ts (233 lines) - Credential management
- src/utils/debouncer.ts (183 lines) - Message batching
1. Message type filtering - Only process "notify" and "append" types
2. Status/broadcast filtering - Skip @status and @broadcast messages
3. Improved deduplication - Use whatsapp:remoteJid:messageId key
4. History handling - Skip auto-reply for "append" type messages
5. Credentials backup - Backup and validate before saving
6. Read receipts - Send for all messages (except self-chat)
7. WebSocket error handling - Prevent crashes from socket errors
8. Group metadata caching - 5min TTL, reduces API calls
9. Connection timestamp filtering - Skip old messages on reconnect
10. Message debouncing - Batch rapid consecutive messages
11. Full type safety - Replaced 26+ 'any' with proper Baileys types
Implements getMessage callback pattern to solve delivery failures:
- Store sent messages for 24h retry capability
- Storage happens at SEND-TIME (not upsert-time) to avoid race conditions
- Prevents "waiting for this message" errors and single tick issues
- Based on Baileys issue #1767 solution
Key insight: Storing messages in messages.upsert listener interferes with
consecutive message processing. Storing at send-time eliminates race conditions.
Full TypeScript type safety with proper Baileys types:
- Imported WASocket, WAMessage, proto.IMessage from Baileys
- Replaced 26+ instances of 'any' with proper types
- Added null checks for type safety
- All functions properly typed
Impact: Both message delivery AND consecutive message handling now work.
Based on OpenClaw analysis and Baileys community solutions.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* feat(whatsapp): integrate PR #64 attachment support into modular structure
Port attachment download/upload features from PR #64 to our refactored
modular WhatsApp architecture.
## Features Added
- Media download (images, videos, audio, documents, stickers)
- Media upload (images and documents with captions)
- Size limit enforcement (attachmentsMaxBytes config)
- Metadata-only mode (0 bytes = no download)
- Organized storage (attachmentsDir/whatsapp/chatId/)
## Architecture
Created new module: inbound/media.ts (173 lines)
- unwrapMessageContent() - Unwraps ephemeral/viewOnce messages
- extractMediaPreview() - Quick media detection
- collectAttachments() - Download and save media
- extensionFromMime() - MIME type to extension conversion
Updated modules:
- inbound/types.ts - Added attachments field, AttachmentExtractionConfig
- inbound/extract.ts - Integrated media extraction
- types.ts - Added attachmentsDir, attachmentsMaxBytes to config
- outbound.ts - Added sendFile() for image/document sending
- index.ts - Wired attachment config throughout
## Integration Pattern
Attachments are opt-in via configuration:
- If attachmentsDir configured → Downloads enabled
- If not configured → Text-only mode (backward compatible)
- downloadContentFromMessage imported from Baileys dynamically
- Attachment config passed through extraction pipeline
## Maintains
- ✅ Consecutive message handling
- ✅ getMessage delivery pattern
- ✅ Full type safety
- ✅ Modular architecture
- ✅ All existing functionality
Based on PR #64 by Cameron and Jason, integrated into modular structure.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* feat(whatsapp): add addReaction stub for API completeness
Add addReaction method stub to match upstream API.
Currently a no-op as Baileys reactions not yet supported.
Ensures complete ChannelAdapter interface compatibility.
---------
Co-authored-by: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
|
2026-02-02 12:47:23 -08:00 |
|