feat: implement WhatsApp Business Cloud API integration for Eliza App#320
feat: implement WhatsApp Business Cloud API integration for Eliza App#320
Conversation
- Added WhatsApp authentication endpoint to handle user sessions via WhatsApp ID, enabling auto-provisioning of users on first message. - Implemented a public webhook to receive and route messages from the WhatsApp Cloud API, supporting cross-platform user linking with Telegram and iMessage. - Enhanced user service methods to manage WhatsApp identity, including database migrations for WhatsApp-specific fields and constraints. - Updated environment configuration and README to include WhatsApp settings, ensuring proper setup for deployment. This integration expands the Eliza App's capabilities, allowing seamless communication through WhatsApp and improving user experience across platforms.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Use the checkbox below for a quick retry:
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
PR Review: WhatsApp Integration for Eliza AppOverall Assessment: ✅ Excellent This is a well-architected, production-ready WhatsApp integration. The code demonstrates strong engineering practices with comprehensive testing, proper security measures, and thoughtful cross-platform account linking. 🎯 StrengthsArchitecture & Design
Security ✓
Database Migration ✓
Test Coverage ✓
Code Quality
🔍 Observations & Recommendations1. Webhook Retry Logic (
|
- Introduced new columns for WhatsApp ID in the users table to support WhatsApp authentication. - Ensured idempotency in the migration with the use of IF NOT EXISTS. - Generated migration script using drizzle-kit for consistency with existing database migration practices.
Code Review: WhatsApp Integration (PR #320)SummaryThis WhatsApp Business Cloud API integration is well-architected with strong security practices, comprehensive error handling, and excellent race condition mitigation. The code follows existing patterns from Discord/Telegram integrations and includes robust test coverage. Overall Assessment: ✅ Approve with minor fixes recommended Critical Issues (Must Fix Before Merge)🔴 1. Environment Variable Validation Bypass in ProductionFile: The WhatsApp config uses empty string fallbacks which won't throw errors in production if variables are missing: whatsapp: {
accessToken: requireEnv("ELIZA_APP_WHATSAPP_ACCESS_TOKEN", ""), // ❌ Empty fallback
phoneNumberId: requireEnv("ELIZA_APP_WHATSAPP_PHONE_NUMBER_ID", ""),
appSecret: requireEnv("ELIZA_APP_WHATSAPP_APP_SECRET", ""),
// ...
}The Fix: whatsapp: {
accessToken: requireEnv("ELIZA_APP_WHATSAPP_ACCESS_TOKEN"), // ✅ No fallback = required
phoneNumberId: requireEnv("ELIZA_APP_WHATSAPP_PHONE_NUMBER_ID"),
appSecret: requireEnv("ELIZA_APP_WHATSAPP_APP_SECRET"),
verifyToken: requireEnv("ELIZA_APP_WHATSAPP_VERIFY_TOKEN"),
phoneNumber: requireEnv("ELIZA_APP_WHATSAPP_PHONE_NUMBER"),
}This matches the pattern used for Important Improvements (Recommended)🟡 2. Missing
|
- Added functions to clean up user data based on Discord and WhatsApp IDs, expanding the script's capabilities for managing user accounts across multiple platforms. - Updated the cleanup process to include new identifiers and improved logging for better visibility during cleanup operations. - Modified usage instructions to reflect the new options for Discord and WhatsApp, ensuring users can easily utilize the updated script.
Code Review: WhatsApp Business Cloud API IntegrationSummaryThis is a comprehensive, well-architected WhatsApp integration that follows established patterns in the codebase. The implementation demonstrates strong attention to security, error handling, and cross-platform account linking. Overall quality is excellent. Strengths1. Security Best Practices
2. Excellent Error Handling
3. Database Migration Quality
4. Cross-Platform Architecture
5. Code Quality
6. Test Coverage
Issues FoundCritical IssuesNone! No security vulnerabilities or critical bugs detected. High Priority1. Missing Production Validation in Config (lib/services/eliza-app/config.ts:70-76) The config validates Telegram/Blooio in production but not WhatsApp. This could lead to silent failures in production if WhatsApp env vars are missing. Recommendation: Add WhatsApp validation in the production block to validate accessToken, phoneNumberId, appSecret, and verifyToken. Medium Priority2. Type Assertion Safety (app/api/eliza-app/webhook/whatsapp/route.ts:148) Using "as never" type assertion is unsafe. Consider fixing upstream type signature in userContextService.buildContext to accept UserWithOrganization. 3. Potential Memory Issue in Read Receipts (route.ts:79-83) markWhatsAppMessageAsRead fires asynchronously without awaiting. While non-blocking is good for UX, consider using Promise.allSettled if scaling to long-running processes. Low Priority4. Duplicated Phone Masking Logic Phone masking appears in multiple places. Consider extracting to a utility: maskPhoneForLogs(phone: string) 5. Hardcoded Model IDs (config.ts:29-32) Both smallModel and largeModel use the same model. If intentional, add a comment. Security AssessmentPassed
Recommendations
Performance ConsiderationsGood
Optimization Opportunities
RecommendationsMust Fix Before Merge
Should Fix
Nice to Have
Final VerdictAPPROVE with minor requested changes This PR demonstrates exceptional code quality and follows all project conventions. The only blocking issue is the missing production validation for WhatsApp config, which is a 2-line fix. The implementation is:
Estimated Merge Readiness: 95% (pending config validation fix) Great work! 🎉 |
- Introduced new fields for WhatsApp ID and name in the UserInfoResponse interface to enhance user data retrieval. - Updated the handleGetUser function to include WhatsApp information in the user response, improving cross-platform user experience.
PR Review: WhatsApp Business Cloud API IntegrationOverall AssessmentThis is a high-quality, production-ready implementation of WhatsApp support for the Eliza App. The code demonstrates excellent security practices, comprehensive error handling, and thorough test coverage. The architecture follows established patterns from the existing Telegram/Discord integrations. ✅ StrengthsSecurity
Error Handling
Database Design
Code Quality
Testing
🔍 Observations & Recommendations1. Lock TTL vs Function TimeoutFile: The lock TTL is set to 120s to match Recommendation: Consider setting lock TTL slightly higher (e.g., 130s) to ensure cleanup, or add a background job to clean up stale locks. 2. WhatsApp ID Validation ConsistencyFiles:
Both enforce 7-15 digits, which is correct for E.164. Good consistency. 3. Error Handling in
|
…n management - Updated Discord and Telegram authentication handlers to include WhatsApp ID in user data. - Enhanced session management to accommodate WhatsApp ID in session payloads. - Modified configuration to include WhatsApp-related settings for improved integration.
PR Review: WhatsApp Business Cloud API IntegrationOverall AssessmentThis is a well-architected and comprehensive implementation of WhatsApp integration for the Eliza App. The code follows established patterns, includes excellent test coverage, and demonstrates strong security practices. The PR is production-ready with only minor recommendations for improvement. ✅ Strengths1. Security Best Practices
2. Database Design
3. Concurrency & Race Condition Handling
4. Cross-Platform Account Linking
5. Test Coverage
🔍 Code Quality IssuesCriticalNone identified. High Priority1. Missing Error Handling for WhatsApp API Failures (app/api/eliza-app/webhook/whatsapp/route.ts:178-179) The code sends responses but doesn't handle partial failures well: if (responseText) {
await sendWhatsAppResponse(msg.from, responseText);
}
return true; // Always returns true, even if send failsImpact: If the WhatsApp send API fails, the message is marked as processed and won't retry. Recommendation: Check the return value of if (responseText) {
const sent = await sendWhatsAppResponse(msg.from, responseText);
if (!sent) return false; // Don't mark as processed, allow retry
}Medium Priority2. Incomplete Comment Syntax (lib/services/eliza-app/user-service.ts:957, 989) Lines 957 and 989 have malformed comments: / Scenario 1: Check if user exists by whatsapp_idShould be: // Scenario 1: Check if user exists by whatsapp_id3. Hardcoded WhatsApp API Version (lib/utils/whatsapp-api.ts:11) export const WHATSAPP_API_BASE = "https://graph.facebook.com/v21.0";Recommendation: Make the API version configurable via environment variable with a sensible default: const WHATSAPP_API_VERSION = process.env.WHATSAPP_API_VERSION || "v21.0";
export const WHATSAPP_API_BASE = `https://graph.facebook.com/${WHATSAPP_API_VERSION}`;4. Potential Memory Leak in Background Task (app/api/eliza-app/webhook/whatsapp/route.ts:79-83) The markWhatsAppMessageAsRead(WA_ACCESS_TOKEN, WA_PHONE_NUMBER_ID, msg.messageId)
.catch((err) => logger.warn(...)); // Fire-and-forgetRecommendation: This is acceptable as-is since read receipts are non-critical, but document this as intentional fire-and-forget. Low Priority5. Type Assertion Safety (app/api/eliza-app/webhook/whatsapp/route.ts:148) user: { ...userWithOrg, organization } as never,The 6. Missing Retry Logic for WhatsApp API Calls (lib/utils/whatsapp-api.ts:208-244) While the webhook retry handles failures, the WhatsApp send functions don't have built-in retry logic. Consider adding exponential backoff for transient failures (5xx errors, rate limits). 🛡️ Security Considerations✅ Secure
|
- Updated the message handling function to include a retry mechanism for sending responses via WhatsApp. - Added logging for failed send attempts, allowing the webhook to retry if the message fails to send, improving reliability in message delivery.
Comprehensive Code Review - PR #320Executive SummaryThis PR implements WhatsApp Business Cloud API integration with auto-provisioning, cross-platform account linking, and webhook signature verification. The implementation is generally solid with good security practices, but has 1 Critical and 4 High severity issues that must be addressed before merging. ❌ Critical Issues (Must Fix)1. Race Condition in Distributed Lock AcquisitionFile: Problem: When lock acquisition fails, the function returns Fix: Implement a "processing" state in the idempotency table: // Before attempting lock acquisition
await markMessageAsProcessing(messageId, ttl=30000); // 30s processing window
const lock = await distributedLocks.acquireRoomLockWithRetry(roomId, 120000, {
maxRetries: 10,
initialDelayMs: 100,
maxDelayMs: 2000,
});
if (!lock) {
// Message is marked as processing, retry will be rejected by idempotency check
logger.error("[ElizaApp WhatsAppWebhook] Failed to acquire room lock", { roomId });
return false;
}
|
Comprehensive Code Review - PR #320Executive SummaryThis PR implements WhatsApp Business Cloud API integration with auto-provisioning, cross-platform account linking, and webhook signature verification. The implementation is generally solid with good security practices, but has 1 Critical and 4 High severity issues that must be addressed before merging. ❌ Critical Issues (Must Fix)1. Race Condition in Distributed Lock AcquisitionFile: Problem: When lock acquisition fails, the function returns Fix: Implement a "processing" state in the idempotency table: // Before attempting lock acquisition
await markMessageAsProcessing(messageId, ttl=30000); // 30s processing window
const lock = await distributedLocks.acquireRoomLockWithRetry(roomId, 120000, {
maxRetries: 10,
initialDelayMs: 100,
maxDelayMs: 2000,
});
if (!lock) {
// Message is marked as processing, retry will be rejected by idempotency check
logger.error("[ElizaApp WhatsAppWebhook] Failed to acquire room lock", { roomId });
return false;
}
|
Code Review - PR #320: WhatsApp IntegrationStatus:
|
Detailed Code FixesIssue #1: Lock Race Condition (CRITICAL)Current Problem:
Fix: Mark as processing before lock attempt Issue #2-5: High Priority FixesType Safety: Remove Medium Priority
Database Migration Review ✅Migration
No issues found in migration. Test Coverage Assessment6 test files added covering:
Recommendation: Add tests for:
|
- Added validation for WhatsApp ID format to enhance message handling and prevent processing of invalid IDs. - Introduced a new function to remove processed marks, allowing for retries on failed message processing. - Updated the user context building to use a properly typed UserWithOrganization object for better type safety. - Refactored the webhook handling logic to ensure idempotency and prevent duplicate processing of messages. These changes enhance the reliability and robustness of the WhatsApp integration in the Eliza App.
Code Review: WhatsApp Integration for Eliza AppI've conducted a comprehensive review of this PR across code quality, security, database migrations, performance, and integration points. Overall, this is a well-structured implementation with strong security practices, but there are several issues that should be addressed. 🎯 Overall AssessmentStrengths:
Key Concerns:
🔴 High Priority IssuesIssue #1: Race Condition in Webhook Idempotency (TOCTOU)File: Problem: Non-atomic check-then-mark pattern: if (await isAlreadyProcessed(idempotencyKey)) {
continue; // ← Check
}
await markAsProcessed(idempotencyKey, "whatsapp-eliza-app"); // ← Mark (gap here!)
const processed = await handleIncomingMessage(msg); // ← ProcessBetween the Recommendation: const claimed = await tryClaimForProcessing(idempotencyKey, "whatsapp-eliza-app");
if (!claimed) {
continue; // Already claimed by another process
}
const processed = await handleIncomingMessage(msg);This uses the atomic Issue #2: Signature Verification Bypass in DevelopmentFile: Problem: const skipVerification =
process.env.SKIP_WEBHOOK_VERIFICATION === "true" &&
process.env.NODE_ENV !== "production";This allows signature verification to be skipped if Recommendation:
🟡 Medium Priority IssuesIssue #3: Auto-Derived Phone Number Could ConflictFile: Problem: WhatsApp ID auto-derives to E.164 phone: const derivedPhone = `+${whatsappId.replace(/\D/g, "")}`;If a WhatsApp ID somehow contains formatting (which Recommendation:
Issue #4: Multiple Database Queries for Cross-Platform LinkingFile: Problem: Sequential lookups without transaction:
Impact: Race window between lines 990-1009 where another request could claim the phone number. The code does check for race conditions after the fact (lines 993-1001), but a database transaction with SERIALIZABLE isolation would be safer. Recommendation: Wrap findOrCreate operations in a transaction: await db.transaction(async (tx) => {
// All lookups and updates here
}, { isolationLevel: 'serializable' });🟢 Low Priority IssuesIssue #5: Loose Phone Number Derivation ValidationFile: The derived phone isn't explicitly validated as E.164. Recommendation: Add E.164 format check immediately after derivation. Issue #6: Redundant Index DefinitionFile: The index on Recommendation: Choose one source of truth (typically migration for manual control, or schema for auto-generation). Issue #7: Double Validation is RedundantFile: WhatsApp ID format is validated twice:
Recommendation: Choose one validation method to avoid maintenance drift. Issue #8: Inconsistent PII Masking in LogsFile: WhatsApp ID masked as Recommendation: Use consistent masking throughout for PII. ✅ Security Review SummaryGood:
Concerns:
✅ Database Migration ReviewExcellent adherence to CLAUDE.md rules:
Minor: Issue #6 about index duplication. 📊 Summary of Findings
🎬 Recommended Actions (Priority Order)
🏆 Overall RecommendationConditional Approval - This is a solid implementation with excellent test coverage and security practices. The issues identified are addressable and mostly involve race condition hardening and configuration safety. I recommend:
Great work on the comprehensive integration! The cross-platform linking logic is particularly well thought out. |
- Added routes for connecting, disconnecting, and checking the status of WhatsApp Business accounts. - Introduced a WhatsApp Automation Service for credential validation, storage, and message management. - Enhanced webhook handling for incoming messages, including signature verification and message processing with retry logic. - Updated environment configuration and documentation to support new WhatsApp features. - Added unit tests for the WhatsApp Automation Service to ensure functionality and reliability.
Code Review: WhatsApp Business Cloud API IntegrationI've completed a comprehensive review of PR #320. This is a well-architected implementation with strong security practices and excellent test coverage. Below are my findings: ✅ Strengths1. Security Implementation
2. Database Design
3. Architecture & Code Quality
4. Test Coverage
🔍 Issues FoundCRITICAL: Missing Comment Syntax in MigrationFile: The migration has a typo that will cause a syntax error: ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "whatsapp_id" text;--> statement-breakpointThe Impact: Migration will fail during deployment. Fix: Change to: ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "whatsapp_id" text; --> statement-breakpoint
ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "whatsapp_name" text; --> statement-breakpointOr remove the comment entirely (it's a Drizzle artifact). 💡 Recommendations (Non-Blocking)1. Webhook Retry Logic (app/api/eliza-app/webhook/whatsapp/route.ts:217-222)The error handling marks messages as processed even on agent failure: } catch (error) {
logger.error("[ElizaApp WhatsAppWebhook] Agent failed", {
error: error instanceof Error ? error.message : String(error),
roomId,
});
return true; // Processing attempted, mark as processed to avoid infinite retry
}Concern: Transient failures (DB timeout, temporary API errors) will silently drop messages. Suggestion: Consider differentiating between retryable errors (503, network issues) and permanent errors (validation, user not found). For retryable errors, return 2. Lock TTL vs maxDuration Mismatch (route.ts:160)const lock = await distributedLocks.acquireRoomLockWithRetry(roomId, 120000, {
maxRetries: 10,
initialDelayMs: 100,
maxDelayMs: 2000,
});With Suggestion: Document this retry strategy or reduce 3. Phone Number Normalization (user-service.ts:955)The auto-derivation assumes WhatsApp IDs are always valid E.164 numbers: const derivedPhone = `+${whatsappId.replace(/\D/g, "")}`;Minor Risk: Some international numbers require country-code-specific formatting. This works for most cases, but edge cases (short codes, special regions) might not normalize correctly. Suggestion: Add a comment documenting this assumption, or use a phone validation library like 4. Missing Rate Limit on GET Webhook (route.ts:344)The GET webhook verification uses export const GET = withRateLimit(handleWhatsAppWebhookGet, RateLimitPresets.STANDARD);Context: Meta only calls this endpoint once during webhook setup, so rate limiting is fine. However, Suggestion: Consider 5. Test Coverage Gap: No Tests for Linking ConflictsThe user service handles WhatsApp linking conflicts (
Suggestion: Add a test case in 📋 Summary
✅ Approval StatusConditionally Approved pending migration syntax fix. The migration syntax error is a blocking issue that will cause deployment failure. Once fixed, this PR is production-ready. All other recommendations are minor improvements that can be addressed in follow-up PRs. Required Before Merge:
Optional Follow-Ups:
Great work on this integration! The code quality, security practices, and test coverage are all excellent. The WhatsApp integration follows the same patterns as the existing Telegram/iMessage implementations, which makes the codebase more maintainable. Let me know if you'd like me to elaborate on any of the recommendations. |
Deleted the migration file for adding WhatsApp identity columns to the users table and updated the migration index in the journal. This change ensures the migration history remains consistent and sequential.
PR Review: WhatsApp Business Cloud API IntegrationI've completed a comprehensive review of PR #320. Overall, this is a well-architected and production-ready implementation with excellent attention to security, error handling, and testing. Below are my findings organized by category. ✅ Strengths1. Excellent Security Implementation
2. Robust Race Condition Handling
3. Smart Cross-Platform Linking
4. Production-Grade Error Handling
5. Comprehensive Test Coverage
6. Clean Migration
🔍 Issues FoundCritical IssuesNone - No critical security vulnerabilities or data integrity issues found. High Priority IssuesNone - No blocking bugs identified. Medium Priority Issues1. Potential Memory Leak in Fire-and-Forget markRead()Location: markRead(); // Fire-and-forget - no awaitIssue: The
Recommendation: Either:
2. Missing Timeout on WhatsApp API Fetch CallsLocation: const response = await fetch(url, {
method: "POST",
headers: { ... },
body: JSON.stringify(body),
// Missing: signal: AbortSignal.timeout(10000)
});Issue: No timeout configured for external API calls to Meta's servers. This could cause:
Recommendation: Add timeout to all fetch calls: signal: AbortSignal.timeout(10000), // 10s timeout3. Hardcoded Retry Count in markRead()Location: const markRead = async (retries = 2) => {Issue: Retry logic is embedded in the webhook handler rather than in the utility function. This makes it:
Recommendation: Move retry logic to Low Priority Issues4. Response Text Extraction Could Be More DefensiveLocation: const responseText =
typeof responseContent === "string"
? responseContent
: responseContent?.text || "";Issue: If Recommendation: Log a warning when the agent returns unexpected content format. 5. Magic Number for Lock TTLLocation: const lock = await distributedLocks.acquireRoomLockWithRetry(roomId, 120000, {Issue: The 120000 (120s) is tied to Recommendation: const LOCK_TTL_MS = maxDuration * 1000;
const lock = await distributedLocks.acquireRoomLockWithRetry(roomId, LOCK_TTL_MS, {6. Phone Number Derivation Assumes E.164 FormatLocation: const derivedPhone = `+${whatsappId.replace(/\D/g, "")}`;Issue: While WhatsApp IDs are typically digits only, the comment assumes E.164 format. However:
Impact: Low - WhatsApp IDs are always in international format, but worth documenting. Recommendation: Add a comment explaining the assumption or use 🎯 Performance ConsiderationsGood Practices
Potential Optimizations
📋 Test Coverage AssessmentExcellent Coverage
Suggested Additional Tests
🔒 Security AssessmentThreats Mitigated ✅
Security Best Practices
Recommendations
📝 Code QualityStrengths
Minor Suggestions
✅ Final VerdictApprove with minor suggestions This PR demonstrates:
The medium-priority issues are non-blocking and can be addressed in a follow-up PR or before merge. The implementation is solid and ready for staging deployment. Recommended Actions Before Merge
Post-Merge Recommendations
Great work on this integration! The attention to detail in race condition handling and cross-platform linking is particularly impressive. 🚀 |
… webhook handlers - Added `startWhatsAppTypingIndicator` and `sendWhatsAppTypingIndicator` functions to manage typing indicators in WhatsApp messages. - Integrated performance tracing in the WhatsApp webhook handlers to monitor key processing stages. - Enhanced user provisioning and message processing logic with improved error handling and logging. - Updated related services to support new typing indicator functionality.
PR Review: WhatsApp Business Cloud API IntegrationOverall this is a well-structured integration with good documentation, Zod validation, HMAC-SHA256 signature verification, and solid idempotency patterns. A few issues need attention before merge, ranging from a security concern to bugs and architecture notes. Security: Auth endpoint authenticates by phone number aloneFile: The // Anyone who knows a valid whatsapp_id gets a session token
const userWithOrg = await elizaAppUserService.getByWhatsAppId(whatsappId);
const session = await elizaAppSessionService.createSession(...);The rate limiting (
Bug: Double
|
Summary
Full-stack WhatsApp integration for the Eliza App public bot. Users can message the WhatsApp number and are auto-provisioned on first contact; replies are generated via the default Eliza agent in ASSISTANT mode. Cross-platform account linking is automatic since WhatsApp IDs are phone numbers — existing Telegram/iMessage users with the same number are linked seamlessly.
Changes
API Routes
POST /api/eliza-app/auth/whatsapp— Issues JWT session tokens for WhatsApp-identified users. Supports standard lookup (user must first message the bot) and session-based linking (existing user attaches WhatsApp to their account via Bearer token).GET /api/eliza-app/webhook/whatsapp— Meta webhook verification handshake (hub.mode,hub.verify_token,hub.challenge).POST /api/eliza-app/webhook/whatsapp— Receives incoming WhatsApp messages, verifies HMAC-SHA256 signature, auto-provisions users, acquires distributed room lock, processes messages through the Eliza runtime in ASSISTANT mode, and sends responses back via the Cloud API.Database
0029_add_whatsapp_identity_columns.sql— Addswhatsapp_id(unique, indexed) andwhatsapp_namecolumns touserstable. Extendsphone_providerandphone_typeenums with'whatsapp'value. Fully idempotent withIF NOT EXISTSguards.db/schemas/users.tsanddb/schemas/agent-phone-numbers.tsupdated with WhatsApp columns and enum values.Services
ElizaAppUserService— Three new methods:findOrCreateByWhatsAppId()— Auto-provisions users on first WhatsApp message with 3-way cross-platform linking (bywhatsapp_id, byphone_number, or new user). Includes race-condition handling with unique constraint recovery.getByWhatsAppId()— Lookup by WhatsApp ID with organization data.linkWhatsAppToUser()— Session-based linking with idempotency and conflict detection.WhatsAppAuthService(whatsapp-auth.ts) — Verifies webhook POST signatures (X-Hub-Signature-256) and GET subscription handshakes.MessageRouterService— Extended withwhatsappprovider andsendViaWhatsApp()method using the Cloud API.Utilities
whatsapp-api.ts(new, 304 lines) — Complete WhatsApp Cloud API utility layer:parseWhatsAppWebhookPayload,extractWhatsAppMessages)sendWhatsAppMessage) with retry and error handlingmarkWhatsAppMessageAsRead)verifyWhatsAppSignature)deterministic-uuid.ts— Extendedchannelunion type with'whatsapp'for room/entity ID generation.Repository
UsersRepository— AddedfindByWhatsAppId()andfindByWhatsAppIdWithOrganization()query methods.Configuration
elizaAppConfig— Newwhatsappsection withaccessToken,phoneNumberId,appSecret,verifyToken, andphoneNumber..env.local.example— Documented all 5 WhatsApp environment variables with setup instructions.README.md— Updated Eliza App variables section to include WhatsApp.Tests (6 new test files)
tests/unit/eliza-app/whatsapp-auth.test.ts— WhatsApp auth service unit teststests/unit/eliza-app/whatsapp-webhook.test.ts— Webhook handler unit teststests/unit/eliza-app/cross-platform-linking.test.ts— Cross-platform account linking scenariostests/unit/whatsapp-api-util.test.ts— WhatsApp API utility tests (390 lines)tests/unit/message-router-service.test.ts— Message router WhatsApp provider teststests/integration/whatsapp-webhook-e2e.test.ts— End-to-end webhook integration testsTest Plan
npx jest --testPathPattern whatsapp— all 6 test files passwhatsapp_idandwhatsapp_namePOST /api/eliza-app/auth/whatsappwith Bearer tokenRelated
feat/whatsapp-supportoneliza-app(onboarding flow, connected page, auth context)