Inbound Email Client
Relevant source files
The following files were used as context for generating this wiki page:
The Inbound Email Client is a specialized system designed to allow users to interact with the Recoup AI assistant directly via email. It transforms standard email communication into a managed chat experience, ensuring that conversations remain synchronized between email threads and the web-based platform. By leveraging webhooks and AI agents, the system automates response generation, thread tracking, and database persistence.
The system primary functions by receiving emails through a third-party service, processing them through a series of validation and AI-driven logic steps, and returning a threaded reply to the user. This creates a "seamless email-based chat experience with full conversation continuity."
Sources: features/feature-email-client.md:3-9, lib/chat/const.ts:3-10
Architecture and Data Flow
The architecture is built around a webhook-driven flow that integrates external email services (Resend) with internal AI agents and Supabase storage.
High-Level Webhook Flow
When an email is sent to a Recoup address (e.g., support@mail.recoupable.com), it triggers a POST request to the application's webhook endpoint.
The system identifies the sender, fetches the full email content, and determines if the email belongs to an existing conversation "room" or requires the creation of a new one.
Sources: features/feature-email-client.md:14-25, app/api/emails/inbound/route.ts
Threading and Memory Management
The system uses the email References and In-Reply-To headers to maintain thread continuity. This mapping ensures that even if a user switches between email and the web interface, the AI retains the full context of the conversation.
| Header / Field | Purpose |
|---|---|
In-Reply-To | Used in outbound emails to maintain threading in the user's inbox. |
References | Parsed from inbound emails to map the thread to a specific room_id. |
email_id | Used as a unique identifier to prevent duplicate processing (Idempotency). |
Inbound Domain | @mail.recoupable.com (where emails are received). |
Outbound Domain | @recoupable.com (where replies are sent from). |
Sources: features/feature-email-client.md:301-315, lib/emails/inbound/tests/getFromWithName.test.ts:7-15
Core Components
1. Webhook Entry Point
The entry point for all inbound email processing is app/api/emails/inbound/route.ts. This route accepts POST requests from Resend, specifically looking for email.received events.
2. Orchestration (handleInboundEmail)
The handleInboundEmail() function acts as the primary coordinator. It handles:
- Validation: Ensuring the webhook payload follows the expected Zod schema.
- Response Coordination: Triggering
respondToInboundEmail()to manage the logic of reading, thinking, and replying. - Test Detection: Identifying if an email is a test to skip certain production-only logic.
Sources: features/feature-email-client.md:46-60, lib/emails/inbound/handleInboundEmail.ts
3. AI Agent Integration
The system utilizes a GeneralAgent to generate responses. This agent is configured with a music-industry-specific SYSTEM_PROMPT that defines its persona as "Recoup," a strategic assistant for music executives and artists.
4. Content Processing
- Trim Replied Context: The system strips quoted text from previous replies (e.g., "On Monday, User wrote...") to ensure the AI only processes the new message content.
- Knowledge Base Integration: If the user is associated with an artist, the agent can pull context from an uploaded knowledge base (PDFs, text files, etc.).
- Footer Generation: Every reply includes a horizontal rule and a link to "Continue the conversation on Recoup," allowing a transition to the web chat.
Sources: features/feature-email-client.md:316-322, lib/emails/tests/getEmailFooter.test.ts:20-30
Database Schema Relations
The system relies on several tables within Supabase to track accounts and conversations.
Key Implementation Details
Duplicate Prevention (Idempotency)
To prevent the AI from responding twice to the same email (e.g., due to webhook retries), the system uses the email_id from Resend as the primary key or a unique constraint in the memories table. If an insertion fails with a unique constraint error (PostgreSQL code 23505), the system terminates processing for that event silently.
Sources: features/feature-email-client.md:265-280
Domain Conversion
Inbound emails arrive at the subdomain @mail.recoupable.com. However, for a professional appearance, outbound replies are converted to the primary domain @recoupable.com. The formatting logic also capitalizes the name of the mailbox (e.g., support becomes Support by Recoup).
Sources: lib/emails/inbound/tests/getFromWithName.test.ts:7-15
Conclusion
The Inbound Email Client is a robust bridge between traditional email communication and modern AI-driven management. By maintaining strict thread continuity and utilizing music-industry-specialized prompts, it provides a consistent assistant experience across platforms. The architecture's focus on idempotency and clean content processing ensures reliability and professional communication standards.