/** * Mailgun Email Service * This service handles email sending via Mailgun API */ import { getMailgunConfig, type MailgunConfig } from './mailgun.config'; import { getAppConfig } from '../config/unified.config'; interface EmailTemplate { subject: string; html: string; text?: string; } export class MailgunService { private config: MailgunConfig; constructor() { this.config = getMailgunConfig(); // Log configuration status on startup const status = this.getConfigurationStatus(); if (status.mode === 'development') { console.warn( '📧 Mailgun Service: Running in development mode (emails will be logged only)' ); console.warn( '💡 To enable real emails, configure Mailgun credentials in .env.local' ); } else { console.warn( '📧 Mailgun Service: Configured for production with domain:', status.domain ); } } private getVerificationEmailTemplate(verificationUrl: string): EmailTemplate { return { subject: 'Verify Your Email - Medication Reminder', html: `

Verify Your Email Address

Thank you for signing up for Medication Reminder! Please click the button below to verify your email address:

Verify Email Address

Or copy and paste this link into your browser:

${verificationUrl}

This link will expire in 24 hours.

`, text: ` Verify Your Email - Medication Reminder Thank you for signing up! Please verify your email by visiting: ${verificationUrl} This link will expire in 24 hours. `, }; } private getPasswordResetEmailTemplate(resetUrl: string): EmailTemplate { return { subject: 'Reset Your Password - Medication Reminder', html: `

Reset Your Password

You requested to reset your password. Click the button below to set a new password:

Reset Password

Or copy and paste this link into your browser:

${resetUrl}

This link will expire in 1 hour. If you didn't request this, please ignore this email.

`, text: ` Reset Your Password - Medication Reminder You requested to reset your password. Visit this link to set a new password: ${resetUrl} This link will expire in 1 hour. If you didn't request this, please ignore this email. `, }; } async sendEmail(to: string, template: EmailTemplate): Promise { try { // Production Mailgun API call const formData = new FormData(); formData.append( 'from', `${this.config.fromName} <${this.config.fromEmail}>` ); formData.append('to', to); formData.append('subject', template.subject); formData.append('html', template.html); if (template.text) { formData.append('text', template.text); } const response = await fetch( `${this.config.baseUrl}/${this.config.domain}/messages`, { method: 'POST', headers: { Authorization: `Basic ${btoa(`api:${this.config.apiKey}`)}`, }, body: formData, } ); if (!response.ok) { const errorText = await response.text(); throw new Error(`Mailgun API error: ${response.status} - ${errorText}`); } const result = await response.json(); console.warn('📧 Email sent successfully via Mailgun:', { to, subject: template.subject, messageId: result.id, }); return true; } catch (error: unknown) { console.error('Email sending failed:', error); return false; } } async sendVerificationEmail(email: string, token: string): Promise { const verificationUrl = `${getAppConfig().baseUrl}/verify-email?token=${token}`; const template = this.getVerificationEmailTemplate(verificationUrl); return this.sendEmail(email, template); } async sendPasswordResetEmail(email: string, token: string): Promise { const resetUrl = `${getAppConfig().baseUrl}/reset-password?token=${token}`; const template = this.getPasswordResetEmailTemplate(resetUrl); return this.sendEmail(email, template); } // Get configuration status for debugging getConfigurationStatus(): { configured: boolean; mode: 'development' | 'production'; domain: string; fromEmail: string; } { const configured = !!this.config.apiKey && !!this.config.domain && !!this.config.baseUrl && !!this.config.fromEmail && !!this.config.fromName; const mode: 'development' | 'production' = configured ? 'production' : 'development'; return { configured, mode, domain: this.config.domain, fromEmail: this.config.fromEmail, }; } } export const mailgunService = new MailgunService();