Overview
The email channel allows users to interact with CORE by sending emails. CORE processes incoming emails, runs them through the AI pipeline, and sends replies back via email. Capabilities:- Inbound email processing via Resend webhooks
- Outbound email replies via Resend API
- Plain text email responses
- No typing indicators (email doesn’t support this)
- No acknowledge messages (no intermediate “processing…” emails)
- No email threading via Message-ID/In-Reply-To headers (threading is subject-line based only)
- Plain text replies only (no rich HTML formatting in AI responses)
- No attachment support
- No webhook signature verification (see Security Notes)
Prerequisites
- A Resend account
- A verified domain in Resend for sending emails
- Resend Inbound configured to receive emails
Environment Variables
Add these to your.env file:
Resend Configuration
1. Get Your API Key
- Go to Resend Dashboard
- Create a new API key with full access (needed for both sending and receiving)
- Copy the key to
RESEND_API_KEY
2. Verify Your Domain
- Go to Resend Domains
- Add your domain and follow DNS verification steps
- Wait for verification to complete
3. Configure Inbound Email
- Go to Resend Inbound
- Set up an inbound address (e.g.,
brain@yourdomain.com) - Add MX records as instructed by Resend
- Configure the webhook endpoint:
- Select the
email.receivedevent type
4. Set FROM_EMAIL
SetFROM_EMAIL to match your inbound email address:
- Filter incoming emails (only emails addressed to this address are processed)
- Set the Reply-To header on outbound emails
Webhook Route
Inbound emails are received at:- Validates the event type is
email.received - Checks the recipient matches
FROM_EMAIL - Fetches the full email body from Resend API
- Looks up the sender by email address in your user database
- Routes the message through the CORE AI pipeline
- Sends a reply to the sender
How It Works
Inbound Flow
- User sends email to
brain@yourdomain.com - Resend receives the email and sends a webhook to
/api/v1/channels/email - CORE fetches the email body using
resend.emails.receiving.get(email_id) - If the sender is a registered user, the message is processed
- AI generates a response
- Response is sent back via email
Outbound Flow
- AI generates a response
- CORE sends email via
resend.emails.send() - Subject is prefixed with
Re:if replying to a thread
User Registration
Only registered users can interact via email. The sender’s email address must exist in the CORE user database with an associated workspace. Emails from unknown senders are logged but not processed.File Locations
| File | Purpose |
|---|---|
apps/webapp/app/services/channels/email/inbound.ts | Webhook parsing |
apps/webapp/app/services/channels/email/outbound.ts | Reply sending |
apps/webapp/app/services/channels/email/index.ts | Channel registration |
packages/emails/src/transports/resend.ts | Resend transport |
apps/webapp/app/routes/api.v1.channels.$channel.tsx | Webhook route |
Troubleshooting
Emails not being received
- Check Resend Inbound logs for delivery status
- Verify MX records are correctly configured
- Confirm webhook URL is accessible from the internet
- Check
FROM_EMAILmatches the inbound address
Emails received but not processed
- Verify sender is a registered user in CORE
- Check logs for “Email from unknown sender” warnings
- Confirm user has an associated workspace
Replies not being sent
- Check
RESEND_API_KEYhas send permissions - Verify domain is verified in Resend
- Check application logs for Resend API errors
Empty email body
- Some email clients send HTML-only emails
- The handler extracts
textfirst, then falls back tohtml - Check Resend logs to see the raw email content
Security Notes
- No webhook signature verification: The
RESEND_WEBHOOK_SECRETenvironment variable is defined but not currently implemented. Anyone who knows your webhook URL could potentially send fake events. - Sender validation: Only processes emails from registered users, which provides some protection.
- Recipient filtering: Only processes emails addressed to
FROM_EMAIL.
Comparison with Other Channels
| Feature | Slack | ||
|---|---|---|---|
| Typing indicators | No | No | Yes |
| Acknowledge messages | No | Yes | Yes |
| Rich formatting | No (plain text) | Limited | Yes |
| Thread tracking | Subject-based | Yes | Yes |
| Attachments | No | Yes | Yes |
