← back to Dear Bubbe Nextjs

app/api/email/route.ts

213 lines

import { NextRequest, NextResponse } from 'next/server'
import { updateStat } from '../stats/route'

interface EmailRequest {
  to: string | string[]
  subject: string
  body: string
  html?: string
  from?: string
}

// Mock email sending - replace with actual email service
async function sendEmail(emailData: EmailRequest): Promise<{ success: boolean; messageId?: string; error?: string }> {
  try {
    // This is a mock implementation - replace with your email service
    // Examples: SendGrid, AWS SES, Nodemailer with SMTP, etc.
    
    console.log(`[EMAIL] Sending email to: ${Array.isArray(emailData.to) ? emailData.to.join(', ') : emailData.to}`)
    console.log(`[EMAIL] Subject: ${emailData.subject}`)
    console.log(`[EMAIL] Body length: ${emailData.body.length} characters`)
    
    // Simulate email sending delay
    await new Promise(resolve => setTimeout(resolve, 1000))
    
    // Mock success response
    const messageId = `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
    
    return {
      success: true,
      messageId
    }
  } catch (error) {
    console.error('[EMAIL] Error sending email:', error)
    return {
      success: false,
      error: error instanceof Error ? error.message : String(error)
    }
  }
}

// Generate email template
function generateEmailTemplate(subject: string, body: string): string {
  return `
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${subject}</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
      line-height: 1.6;
      color: #333;
      max-width: 600px;
      margin: 0 auto;
      padding: 20px;
      background-color: #f5f5f5;
    }
    .email-container {
      background: white;
      padding: 30px;
      border-radius: 8px;
      box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    }
    .header {
      border-bottom: 2px solid #f093fb;
      padding-bottom: 20px;
      margin-bottom: 30px;
    }
    .content {
      white-space: pre-wrap;
    }
    .footer {
      margin-top: 30px;
      padding-top: 20px;
      border-top: 1px solid #eee;
      font-size: 12px;
      color: #666;
      text-align: center;
    }
    a {
      color: #f5576c;
      text-decoration: none;
    }
    a:hover {
      text-decoration: underline;
    }
  </style>
</head>
<body>
  <div class="email-container">
    <div class="header">
      <h1 style="margin: 0; color: #f5576c;">${subject}</h1>
    </div>
    <div class="content">
      ${body}
    </div>
    <div class="footer">
      <p>Sent from Bubbe.ai | <a href="https://bubbe.ai">Visit Website</a></p>
      <p>This email was sent by an automated system. Please do not reply to this email.</p>
    </div>
  </div>
</body>
</html>
  `.trim()
}

export async function POST(request: NextRequest) {
  try {
    const startTime = Date.now()
    const body = await request.json()

    const { to, subject, body: emailBody, html, from } = body

    // Validation
    if (!to || !subject || !emailBody) {
      return NextResponse.json({
        error: 'Missing required fields: to, subject, body'
      }, { status: 400 })
    }

    // Validate email addresses
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    const toEmails = Array.isArray(to) ? to : [to]
    
    for (const email of toEmails) {
      if (!emailRegex.test(email)) {
        return NextResponse.json({
          error: `Invalid email address: ${email}`
        }, { status: 400 })
      }
    }

    const emailData: EmailRequest = {
      to,
      subject,
      body: emailBody,
      html: html || generateEmailTemplate(subject, emailBody),
      from: from || 'noreply@bubbe.ai'
    }

    console.log(`[EMAIL] Processing email request`)

    const result = await sendEmail(emailData)

    if (result.success) {
      // Update stats
      updateStat('emailCampaignsDrafted', 1)
      updateStat('tasksCompleted', 1)

      const responseTime = Date.now() - startTime
      console.log(`[EMAIL] Email sent successfully in ${responseTime}ms`)

      return NextResponse.json({
        success: true,
        messageId: result.messageId,
        recipients: toEmails.length,
        responseTime
      })
    } else {
      // Update error stats
      updateStat('errorsToday', 1)

      return NextResponse.json({
        error: 'Failed to send email',
        details: result.error
      }, { status: 500 })
    }
  } catch (error) {
    console.error('[EMAIL] Error processing email request:', error)
    
    // Update error stats
    updateStat('errorsToday', 1)
    
    return NextResponse.json({
      error: 'Internal server error',
      details: error instanceof Error ? error.message : String(error)
    }, { status: 500 })
  }
}

export async function GET(request: NextRequest) {
  try {
    // Return email sending capabilities and templates
    return NextResponse.json({
      service: 'Bubbe.ai Email Service',
      features: [
        'HTML email templates',
        'Multiple recipients',
        'Custom subjects and content',
        'Automatic template generation'
      ],
      limits: {
        maxRecipients: 100,
        maxSubjectLength: 200,
        maxBodyLength: 50000
      },
      templates: {
        marketing: 'Professional marketing email template',
        notification: 'Simple notification template',
        welcome: 'Welcome message template'
      },
      usage: 'POST with { to, subject, body } to send email'
    })
  } catch (error) {
    console.error('[EMAIL] Error in GET request:', error)
    return NextResponse.json({ 
      error: 'Failed to process request',
      details: error instanceof Error ? error.message : String(error)
    }, { status: 500 })
  }
}