sanket3280/code-execution
0
1const nodemailer = require('nodemailer');2const brevo = require('@getbrevo/brevo');3 4class EmailService {5 constructor() {6 const { config } = require('../config/env.config');7 8 // Silent initialization9 10 if (config.isProduction && config.email.brevo.apiKey) {11 // Production: Brevo API (Works on Render - HTTPS, no port blocking)12 this.fromEmail = config.email.brevo.email;13 this.useBrevoAPI = true;14 15 const apiInstance = new brevo.TransactionalEmailsApi();16 const apiKey = apiInstance.authentications.apiKey;17 apiKey.apiKey = config.email.brevo.apiKey;18 this.brevoClient = apiInstance;19 20 } else {21 // Development: Gmail SMTP (Works on localhost)22 this.fromEmail = config.email.gmail.user;23 this.useBrevoAPI = false;24 25 if (config.email.gmail.user && config.email.gmail.pass) {26 this.transporter = nodemailer.createTransport({27 service: 'gmail',28 auth: {29 user: config.email.gmail.user,30 pass: config.email.gmail.pass31 }32 });33 }34 }35 }36 37 async sendOTP(email, otp, name = null) {38 const { config } = require('../config/env.config');39 if (config.isDevelopment) {40 console.log('๐ค Sending OTP to:', email);41 }42 43 // Check if email service is configured44 if (!this.useBrevoAPI && !this.transporter) {45 console.error('โ Email service not configured. Please set EMAIL_USER and EMAIL_PASS in .env');46 return false;47 }48 49 try {50 const displayName = name || email.split('@')[0];51 const htmlContent = `52 <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">53 <div style="text-align: center; margin-bottom: 30px;">54 <h1 style="color: #4F46E5; margin: 0;">CodeBattle</h1>55 </div>56 <h2 style="color: #1F2937;">Hi ${displayName},</h2>57 <p style="color: #4B5563; font-size: 16px; line-height: 1.5;">58 Your verification code for CodeBattle:59 </p>60 <div style="background: #F3F4F6; padding: 20px; text-align: center; border-radius: 8px; margin: 30px 0;">61 <div style="font-size: 36px; font-weight: bold; letter-spacing: 8px; color: #4F46E5;">62 ${otp}63 </div>64 </div>65 <p style="color: #6B7280; font-size: 14px;">66 This OTP is valid for <strong>10 minutes</strong>./h1>ou didn't request this, ignore this email.67 </p>68 <hr style="border: none; border-top: 1px solid #E5E7EB; margin: 30px 0;">69 <p style="color: #9CA3AF; font-size: 12px; text-align: center;">70 Best regards,<br>The CodeBattle Team71 </p>72 </div>73 `;74 75 if (this.useBrevoAPI) {76 // Brevo API (Production)77 const sendSmtpEmail = new brevo.SendSmtpEmail();78 sendSmtpEmail.sender = { email: this.fromEmail, name: 'CodeBattle' };79 sendSmtpEmail.to = [{ email: email }];80 sendSmtpEmail.subject = 'CodeBattle - Verification Code';81 sendSmtpEmail.htmlContent = htmlContent;82 83 await this.brevoClient.sendTransacEmail(sendSmtpEmail);84 const { config } = require('../config/env.config');85 if (config.isDevelopment) {86 console.log('โ
OTP sent successfully (Brevo API)');87 }88 } else {89 // Gmail SMTP (Development)90 await this.transporter.sendMail({91 from: `CodeBattle <${this.fromEmail}>`,92 to: email,93 subject: 'CodeBattle - Verification Code',94 html: htmlContent95 });96 const { config } = require('../config/env.config');97 if (config.isDevelopment) {98 console.log('โ
OTP sent successfully (Gmail SMTP)');99 }100 }101 return true;102 } catch (error) {103 console.error('โ Failed to send OTP:', error.message);104 return false;105 }106 }107 108 async sendWelcomeEmail(email, username) {109 // Check if email service is configured110 if (!this.useBrevoAPI && !this.transporter) {111 console.error('โ Email service not configured. Please set EMAIL_USER and EMAIL_PASS in .env');112 return false;113 }114 115 try {116 const htmlContent = `117 <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">118 <div style="text-align: center; margin-bottom: 30px;">119 <h1 style="color: #4F46E5; margin: 0;">CodeBattle Team</h1>120 </div>121 <h2 style="color: #1F2937;">Welcome ${username}! ๐</h2>122 <p style="color: #4B5563; font-size: 16px; line-height: 1.5;">123 Your account has been created. Start coding now!124 </p>125 <div style="text-align: center; margin: 30px 0;">126 <a href="${process.env.CLIENT_URL || 'http://localhost:3000'}" 127 style="background: #4F46E5; color: white; padding: 12px 30px; text-decoration: none; border-radius: 6px; diline-block; font-weight: bold;">128 Start Coding129 </a>130 </div>131 <hr style="border: none; border-top: 1px solid #E5E7EB; margin: 30px 0;">132 <p style="color: #9CA3AF; font-size: 12px; text-align: center;">133 Best regards,<br>The CodeBattle Team134 </p>135 </div>136 `;137 138 if (this.useBrevoAPI) {139 const sendSmtpEmail = new brevo.SendSmtpEmail();140 sendSmtpEmail.sender = { email: this.fromEmail, name: 'CodeBattle' };141 sendSmtpEmail.to = [{ email: email }];142 sendSmtpEmail.subject = 'Welcome to CodeBattle!';143 sendSmtpEmail.htmlContent = htmlContent;144 145 await this.brevoClient.sendTransacEmail(sendSmtpEmail);146 } else {147 await this.transporter.sendMail({148 from: `CodeBattle <${this.fromEmail}>`,149 to: email,150 subject: 'Welcome to CodeBattle!',151 html: htmlContent152 });153 }154 console.log(`โ
Welcome email sent to ${email}`);155 return true;156 } catch (error) {157 console.error('โ Failed to send welcome email:', error.message);158 return false;159 }160 }161}162 163module.exports = new EmailService();164 