Markdown Converter
Agent skill for markdown-converter
This is a **WhatsApp Receipt Processing System** built with **Node.js/Express** that automatically processes receipt images sent via WhatsApp Business API using **Google Document AI** for OCR and expense extraction.
Sign in to like and favorite skills
This is a WhatsApp Receipt Processing System built with Node.js/Express that automatically processes receipt images sent via WhatsApp Business API using Google Document AI for OCR and expense extraction.
Core Purpose: Automate expense reporting by allowing users to send receipt photos via WhatsApp, extract expense data using OCR, and manage approvals through interactive messaging.
āāā src/ ā āāā app.js # Main Express application ā āāā routes/ ā ā āāā whatsapp.js # WhatsApp webhook handlers ā ā āāā health.js # Health check endpoints ā āāā services/ ā ā āāā whatsapp.js # WhatsApp API integration ā ā āāā receiptProcessor.js # OCR and data extraction ā ā āāā storage.js # Data persistence layer ā āāā middleware/ ā ā āāā validation.js # Request validation ā ā āāā errorHandlers.js # Error handling ā āāā utils/ # Utility functions āāā config/ # Configuration files āāā storage/ # Local data storage āāā tests/ # Test files āāā docs/ # Documentation
src/services/whatsapp.js)sendMessage(): Send text messages to userssendInteractiveMessage(): Send buttons/quick repliesgetMediaUrl(): Retrieve media URLs from WhatsAppdownloadMedia(): Download receipt imagesverifyWebhook(): Validate webhook signaturesCopilot Context: This service handles WhatsApp-specific operations. Rate limits apply (1000 messages/day free tier). Always use proper error handling for API calls.
src/services/receiptProcessor.js)processReceipt(): Main processing pipelineprocessWithDocumentAI(): Google Document AI integrationparseReceiptData(): Extract structured expense dataextractMerchant(), extractTotal(), extractDate(): Field-specific extractionCopilot Context: Document AI costs $10/1000 pages. Includes mock OCR fallback for development. Always validate extracted data and handle OCR failures gracefully.
src/services/storage.js)saveReceipt(): Store receipt dataloadReceipt(): Retrieve receipt dataexportToCSV(): Generate expense reportsgetStats(): Usage statisticscleanup(): Remove old filesCopilot Context: Uses JSON file storage with upgrade path to cloud databases. Implements proper file locking and error recovery.
src/routes/whatsapp.js)GET /webhook/whatsapp: Webhook verificationPOST /webhook/whatsapp: Message processingCopilot Context: Webhook responses must be within 20 seconds. Use async processing for time-consuming operations.
// ā GOOD: Proper async/await with error handling async function processReceipt(mediaId, phoneNumber) { try { const mediaUrl = await whatsappService.getMediaUrl(mediaId); const imageBuffer = await whatsappService.downloadMedia(mediaUrl); const ocrResult = await processWithDocumentAI(imageBuffer); return ocrResult; } catch (error) { console.error('ā Receipt processing failed:', error); throw new AppError('Failed to process receipt', 500); } } // ā BAD: Missing error handling and logging async function processReceipt(mediaId, phoneNumber) { const mediaUrl = await whatsappService.getMediaUrl(mediaId); const imageBuffer = await whatsappService.downloadMedia(mediaUrl); return await processWithDocumentAI(imageBuffer); }
AppError class for operational errors// ā GOOD: Structured logging with context console.log('š± Processing WhatsApp message:', { phoneNumber, messageType, timestamp: new Date().toISOString() }); // ā BAD: Plain text logging console.log('Processing message');
/webhook/whatsapp// Handle common WhatsApp API errors if (error.response?.data?.error?.code === 131047) { // User needs to re-engage - send template message await sendReEngagementMessage(phoneNumber); } else if (error.response?.status === 429) { // Rate limit - queue message for retry await queueMessageForRetry(message); }
EXPENSE_PROCESSORus-central1 (default)const expectedFields = { merchant_name: 'string', // Business name total_amount: 'number', // Final amount transaction_date: 'date', // Receipt date tax_amount: 'number', // Tax portion currency: 'string', // Currency code line_items: 'array', // Individual items payment_method: 'string' // Payment type };
ENABLE_MOCK_OCR=true)# 1. Install dependencies npm install # 2. Configure environment cp .env.template .env # Edit .env with your credentials # 3. Start development server npm run dev # 4. Test webhook with ngrok ngrok http 3000 # Use ngrok URL for WhatsApp webhook configuration
ENABLE_MOCK_OCR=true for OCR testing// Enable debug mode process.env.LOG_LEVEL = 'debug'; process.env.DEBUG_WHATSAPP = 'true'; // Test webhook verification curl "http://localhost:3000/webhook/whatsapp?hub.mode=subscribe&hub.challenge=test&hub.verify_token=your_token" // Monitor logs for message processing tail -f logs/app.log
Required for Production:
WHATSAPP_ACCESS_TOKEN=EAA... # From Meta Developer Console WHATSAPP_PHONE_NUMBER_ID=123... # Phone number ID WEBHOOK_VERIFY_TOKEN=secure_token # Webhook verification GOOGLE_CLOUD_PROJECT_ID=project-id # GCP project DOCUMENT_AI_PROCESSOR_ID=processor # Document AI processor
# Build and deploy gcloud run deploy whatsapp-receipts \ --source . \ --platform managed \ --region us-central1 \ --allow-unauthenticated \ --set-env-vars NODE_ENV=production
// Problem: WEBHOOK_VERIFY_TOKEN mismatch // Solution: Ensure token matches Meta Developer Console if (req.query['hub.verify_token'] !== process.env.WEBHOOK_VERIFY_TOKEN) { return res.status(403).send('Invalid verify token'); }
# Problem: Service account lacks permissions # Solution: Add Document AI roles gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \ --role="roles/documentai.apiUser"
// Problem: Rate limits or invalid phone number // Check rate limits and phone number format const phoneRegex = /^\d{10,15}$/; if (!phoneRegex.test(phoneNumber)) { throw new AppError('Invalid phone number format', 400); }
/health - Basic application health/health/ready - Kubernetes readiness probe/health/live - Kubernetes liveness probe// Structured logging for monitoring console.log('š Receipt processed:', { receiptId, phoneNumber, merchant: extractedData.merchant, amount: extractedData.total, processingTime: Date.now() - startTime, success: true });
// Extend message handler in whatsapp.js route const messageHandlers = { text: handleTextMessage, image: handleImageMessage, document: handleDocumentMessage, // NEW location: handleLocationMessage // NEW };
// Extend receiptProcessor.js const processors = { expense: processExpenseReceipt, invoice: processInvoiceDocument, // NEW identity: processIdentityDocument // NEW };
// Replace storage.js with database service // Maintain same interface for backward compatibility class DatabaseStorage { async saveReceipt(receipt) { // PostgreSQL/MongoDB implementation } }
// Security middleware configuration app.use(helmet({ hsts: { maxAge: 31536000, includeSubDomains: true }, noSniff: true, xssFilter: true, referrerPolicy: { policy: 'same-origin' } }));
// ā GOOD: Clear, actionable messages const confirmationMessage = { text: "š Receipt processed!\n\n" + "šŖ Merchant: Starbucks\n" + "š° Total: $12.45\n" + "š Date: 2024-01-15\n\n" + "Please review:", buttons: [ { id: 'approve', title: 'ā Approve' }, { id: 'reject', title: 'ā Reject' }, { id: 'edit', title: 'āļø Edit' } ] }; // ā BAD: Unclear, verbose messages const badMessage = { text: "Your receipt has been processed by our system using optical character recognition technology..." };
"I need to add [feature] to the WhatsApp receipt system. This should integrate with [component] and handle [specific use case]. Please follow the existing patterns in [relevant file] and include proper error handling and logging."
"There's an issue with [component] where [problem description]. The error occurs in [context]. Please investigate the [relevant service/route] and provide a solution that maintains backward compatibility."
"I want to optimize [specific functionality] for better performance. Currently it [current behavior], but it should [desired behavior]. Please suggest improvements while maintaining the existing API contract."
Remember: This system processes personal financial data. Always prioritize security, privacy, and reliability in all code changes. Test thoroughly before deployment, especially webhook integrations and OCR processing.