This repository has been archived in favor of our new monorepo architecture.
👉 Please visit the new monorepo: room302studio/coachartie2
The monorepo contains:
- All services in a single repository
- Simplified deployment and development
- Redis queue-based microservices
- Comprehensive testing and documentation
🤖 TL;DR: Email your AI coach and get intelligent responses with full conversation memory. Just like Discord but via email.
- Users email Coach Artie → Get intelligent coaching responses
- Remembers conversation history (like Discord threads)
- Uses same AI capabilities API as Discord version
- Professional email formatting with threading
You need:
- A VPS/server running Node.js
- A domain name you control
- Cloudflare managing your domain's DNS
- The Coach Artie capabilities API running (see
../coachartie_capabilities/)
- Go to https://resend.com → Sign up
- Add your domain: Go to Domains → Add Domain → Enter
yourdomain.com - Verify domain: Add the DNS records Resend shows you to Cloudflare DNS
- Wait for verification (can take 5-10 minutes)
- Create API key: Go to API Keys → Create API Key → Copy it
- Verify FROM email: Make sure
coach@yourdomain.comis listed as verified
- Go to https://supabase.com → Create new project
- Wait for project creation (takes 2-3 minutes)
- Go to Settings → API → Copy:
Project URL(starts with https://)anon publickey (NOT the service_role key)
# SSH into your server
ssh root@your-server.com
# Clone the repo
git clone https://github.com/your-org/coachartie_email.git
cd coachartie_email
# Install dependencies
npm install
# Create environment file
cp .env.example .env
nano .envFill in your .env file exactly like this:
PORT=3000
RESEND_API_KEY=re_your_actual_key_from_resend
FROM_EMAIL=coach@yourdomain.com
SUPABASE_URL=https://your-project-id.supabase.co
SUPABASE_ANON_KEY=your_anon_key_here
CAPABILITIES_URL=http://localhost:3001 # or wherever your capabilities API runs
WEBHOOK_SECRET=your-super-secret-webhook-password-123WEBHOOK_SECRET should be a long random string you make up. Write it down - you'll need it again for Cloudflare.
Setup the database:
- Go to your Supabase project → SQL Editor
- Run this SQL:
-- Create logs table (if not exists)
CREATE TABLE IF NOT EXISTS logs (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
service TEXT NOT NULL,
level TEXT NOT NULL,
message TEXT NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_logs_service ON logs(service);
CREATE INDEX IF NOT EXISTS idx_logs_timestamp ON logs(timestamp);Build and start the server:
# Build TypeScript
npm run build
# Test it works
npm start
# In another terminal, test the health endpoint
curl http://localhost:3000/health
# Should return: {"status":"ok",...}
# If working, stop it and start with PM2 for production
npm install -g pm2
pm2 start dist/index.js --name coachartie-email
pm2 save
pm2 startup # Follow the instructions it gives you# On your local machine (not server)
npm install -g wrangler
# Login to Cloudflare
wrangler auth login
# This opens a browser - click "Allow" to authorizecd cloudflare
nano wrangler.tomlUpdate the WEBHOOK_URL in wrangler.toml:
[vars]
WEBHOOK_URL = "https://your-server.com/webhook"your-server.com with your actual server domain/IP.
# Deploy the worker code
wrangler deploy
# Set the webhook secret (THE CRITICAL STEP!)
wrangler secret put WEBHOOK_SECRET
# When prompted, enter the EXACT same secret from your .env file
# This is the #1 place people mess up - the secrets MUST match exactly
# Optionally, set approved recipients (recommended for security)
wrangler secret put APPROVED_RECIPIENTS
# When prompted, enter: coach@yourdomain.com,support@yourdomain.com# Check worker is deployed
wrangler list
# Should show "coachartie-email-worker" or similar
# View live logs (keep this open for testing)
wrangler tailIn Cloudflare Dashboard:
-
Go to your domain → Email → Email Routing
-
Enable Email Routing (if not already enabled)
- Click "Enable Email Routing"
- Wait for it to activate (30 seconds)
-
Add Destination Address (required first!)
- Click "Destination addresses" → "Add address"
- Enter:
coach@yourdomain.com(or your support email) - Check your email and click the verification link
- Wait for "Verified" status before continuing
-
Create Custom Address (this is the email people will send to)
- Click "Custom addresses" → "Create address"
- Address:
coach(creates coach@yourdomain.com) - Action: Send to Worker
- Worker: Select
coachartie-email-worker - Click "Create"
-
Verify the Routing Rule
- Should show:
coach@yourdomain.com→Send to Worker: coachartie-email-worker - Status should be "Active"
- Should show:
curl https://your-server.com/health
# Should return: {"status":"ok","timestamp":"..."}# From your server
npm run test:email
# Should see: "✅ Email webhook test successful"- Send email to:
coach@yourdomain.com - Subject:
Hello Coach Artie - Body:
Can you help me set some goals? - Wait 10-30 seconds for response
# Server logs (on your VPS)
tail -f logs/combined.log
# Worker logs (on your local machine)
wrangler tail
# Send test email and watch logs show activity# Install certbot
sudo apt install certbot python3-certbot-nginx
# Get SSL certificate
sudo certbot --nginx -d your-server.com
# Test renewal
sudo certbot renew --dry-runsudo nano /etc/nginx/sites-available/coachartie-emailserver {
listen 80;
server_name your-server.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name your-server.com;
ssl_certificate /etc/letsencrypt/live/your-server.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-server.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}sudo ln -s /etc/nginx/sites-available/coachartie-email /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxPORT=3000 # Server port
RESEND_API_KEY=re_xxxxx # From Resend dashboard → API Keys
FROM_EMAIL=coach@yourdomain.com # Must be verified in Resend
SUPABASE_URL=https://xxx.supabase.co # From Supabase → Settings → API
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiI... # From Supabase → Settings → API (anon public)
CAPABILITIES_URL=http://localhost:3001 # Your Coach Artie capabilities API
WEBHOOK_SECRET=your-long-random-secret-123 # Make this up, use everywhereWEBHOOK_SECRET=your-long-random-secret-123 # MUST match .env file exactly
APPROVED_RECIPIENTS=coach@yourdomain.com # Optional: comma-separated allowed recipients[vars]
WEBHOOK_URL = "https://your-server.com/webhook" # Your VPS webhook endpointCheck 1: Is webhook URL correct?
# In cloudflare/wrangler.toml, should be:
WEBHOOK_URL = "https://your-server.com/webhook" # NOT /webhook/emailCheck 2: Are secrets matching?
# On your server
grep WEBHOOK_SECRET .env
# In Cloudflare (check logs)
wrangler tail
# Send test email, look for auth errorsCheck 3: Is your server reachable?
curl https://your-server.com/health
# Should return 200 OK, not timeoutYour WEBHOOK_SECRET is not matching. The secret must be exactly the same in:
- Your server
.envfile - Cloudflare worker secrets
Fix it:
# On your server, check current secret
grep WEBHOOK_SECRET .env
# Update Cloudflare worker secret to match
wrangler secret put WEBHOOK_SECRET
# Enter the EXACT same valueDomain not verified:
- Go to Resend → Domains
- Check your domain shows "Verified" ✅
- If not, add the DNS records to Cloudflare
- Wait 5-10 minutes and refresh
Wrong FROM_EMAIL:
# Your FROM_EMAIL must be on your verified domain
FROM_EMAIL=coach@yourdomain.com # ✅ Good
FROM_EMAIL=coach@gmail.com # ❌ Bad - not your domainCheck Cloudflare Email Routing setup:
- Domain → Email → Email Routing → Should be "Enabled"
- Custom addresses → Should show
coach@yourdomain.com→Send to Worker - Worker → Should be
coachartie-email-worker
Common mistake: Creating a routing rule instead of a custom address. You need a Custom Address, not a Routing Rule.
# Make sure you're logged in
wrangler whoami
# Should show your Cloudflare email
# If not logged in
wrangler auth login
# Try deploying again
cd cloudflare
wrangler deployMake sure your Coach Artie capabilities API is running:
# Check if it's running
curl http://localhost:3001/health
# or whatever port your capabilities API uses
# Update CAPABILITIES_URL in .env if needed
CAPABILITIES_URL=http://localhost:3001 # or https://your-capabilities-server.com┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ User Email │───▶│ Cloudflare │───▶│ Your VPS │
│ coach@domain.com│ │ Email Worker │ │ Email API │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │
│ ▼
│ ┌─────────────────┐
│ │ Coach Artie │
│ │ Capabilities │
│ └─────────────────┘
│ │
│ ▼
│ ┌─────────────────┐
│ │ Supabase │
│ │ (Memory/Logs) │
│ └─────────────────┘
│ │
│ ▼
│ ┌─────────────────┐
└──────────────▶│ Resend │
│ (Send Response) │
└─────────────────┘
- User sends email to
coach@yourdomain.com - Cloudflare Email Routing receives it
- Cloudflare Worker processes and forwards to your webhook
- Your Email API parses the email and sends to capabilities API
- Coach Artie processes the message and returns response
- Your Email API sends response via Resend
- User receives AI coaching response
# Health check
curl https://your-server.com/health
# Test webhook directly
curl -X POST https://your-server.com/webhook \
-H "Content-Type: application/json" \
-H "X-Webhook-Secret: your-webhook-secret" \
-d '{
"from": "test@example.com",
"to": "coach@yourdomain.com",
"subject": "Test Email",
"messageId": "test-123",
"raw": "From: test@example.com\nTo: coach@yourdomain.com\nSubject: Test\n\nHello Coach Artie!"
}'
# Watch live logs
tail -f logs/combined.log
# Watch Cloudflare Worker logs
wrangler tailUsers can now email coach@yourdomain.com and get intelligent AI coaching responses with full conversation memory, just like Discord but via email.
The system will:
- ✅ Receive emails via Cloudflare
- ✅ Process with Coach Artie capabilities API
- ✅ Remember conversation history
- ✅ Send professional email responses
- ✅ Handle email threading properly
- ✅ Log everything for debugging