169 lines
7.6 KiB
JavaScript
169 lines
7.6 KiB
JavaScript
import nodemailer from 'nodemailer';
|
|
|
|
export default async function handler(req, res) {
|
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
|
|
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
|
|
if (req.method === 'OPTIONS') {
|
|
return res.status(200).end();
|
|
}
|
|
|
|
if (req.method !== 'POST') {
|
|
return res.status(405).json({ error: 'Method Not Allowed' });
|
|
}
|
|
|
|
const { type, name, email, phone, mobile, subject, message, interests, designation, dateTime, resumeName, turnstileToken } = req.body;
|
|
|
|
const contactName = name?.trim();
|
|
const contactEmail = email?.trim();
|
|
const contactPhone = (phone || mobile || '').trim();
|
|
const contactSubject = (subject || interests || type || 'General Inquiry').trim();
|
|
const contactMessage = (message || req.body.comments || '').trim();
|
|
|
|
if (!contactName || !contactEmail) {
|
|
return res.status(400).json({ error: 'Name and Email are required.' });
|
|
}
|
|
|
|
// Verify Cloudflare Turnstile Token
|
|
if (turnstileToken) {
|
|
const secretKey = process.env.TURNSTILE_SECRET_KEY || '1x000000000000000000000000000000AA';
|
|
try {
|
|
const formData = new URLSearchParams();
|
|
formData.append('secret', secretKey);
|
|
formData.append('response', turnstileToken);
|
|
const turnstileRes = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
|
|
method: 'POST',
|
|
body: formData
|
|
});
|
|
const turnstileOutcome = await turnstileRes.json();
|
|
if (!turnstileOutcome.success) {
|
|
return res.status(400).json({ error: 'Cloudflare Turnstile verification failed. Please try again.' });
|
|
}
|
|
} catch (err) {
|
|
console.error('Turnstile verification error:', err);
|
|
}
|
|
}
|
|
|
|
// Determine per-form subject prefix and body label
|
|
let mailSubject, formLabel, accentColor;
|
|
if (type === 'careers') {
|
|
mailSubject = `[Careers Application] New Application from ${contactName}`;
|
|
formLabel = 'Careers / Job Application';
|
|
accentColor = '#38bdf8';
|
|
} else if (type === 'strategy') {
|
|
mailSubject = `[Strategy Call Booking] New Session Request from ${contactName}`;
|
|
formLabel = 'Strategy Call Session Request';
|
|
accentColor = '#38bdf8';
|
|
} else {
|
|
mailSubject = `[Contact Inquiry] ${contactSubject ? contactSubject : `New Inquiry from ${contactName}`}`;
|
|
formLabel = 'Contact Us Inquiry';
|
|
accentColor = '#ffaa00';
|
|
}
|
|
|
|
// 1. Try sending via SMTP (nodemailer)
|
|
const smtpHost = process.env.SMTP_HOST;
|
|
const smtpUser = process.env.SMTP_USER;
|
|
const smtpPass = process.env.SMTP_PASS;
|
|
|
|
if (smtpHost && smtpUser && smtpPass) {
|
|
try {
|
|
const port = parseInt(process.env.SMTP_PORT || '465', 10);
|
|
const secure = process.env.SMTP_SECURE === 'true' || port === 465;
|
|
|
|
const transporter = nodemailer.createTransport({
|
|
host: smtpHost,
|
|
port,
|
|
secure,
|
|
auth: { user: smtpUser, pass: smtpPass },
|
|
tls: { rejectUnauthorized: false }
|
|
});
|
|
|
|
const toEmail = process.env.SMTP_TO || smtpUser;
|
|
const fromEmail = process.env.SMTP_FROM || `"Cavin Infotech" <${smtpUser}>`;
|
|
|
|
let bodyRows = `
|
|
<tr><td style="padding:10px 0;font-weight:600;color:${accentColor};width:140px;">Name:</td><td style="padding:10px 0;color:#fff;">${contactName}</td></tr>
|
|
<tr><td style="padding:10px 0;font-weight:600;color:${accentColor};">Email:</td><td style="padding:10px 0;"><a href="mailto:${contactEmail}" style="color:#38bdf8;text-decoration:none;">${contactEmail}</a></td></tr>
|
|
<tr><td style="padding:10px 0;font-weight:600;color:${accentColor};">Phone:</td><td style="padding:10px 0;color:#fff;">${contactPhone || 'Not provided'}</td></tr>
|
|
`;
|
|
|
|
if (type === 'strategy') {
|
|
bodyRows += `
|
|
<tr><td style="padding:10px 0;font-weight:600;color:${accentColor};">Designation:</td><td style="padding:10px 0;color:#fff;">${designation || 'N/A'}</td></tr>
|
|
<tr><td style="padding:10px 0;font-weight:600;color:${accentColor};">Preferred Slot:</td><td style="padding:10px 0;color:#ffaa00;font-weight:600;">${dateTime || 'Flexible'}</td></tr>
|
|
<tr><td style="padding:10px 0;font-weight:600;color:${accentColor};">Interests:</td><td style="padding:10px 0;color:#fff;">${interests || 'General Consultation'}</td></tr>
|
|
`;
|
|
} else if (type === 'careers') {
|
|
bodyRows += `
|
|
<tr><td style="padding:10px 0;font-weight:600;color:${accentColor};">Resume:</td><td style="padding:10px 0;color:#ffaa00;font-weight:600;">${resumeName || 'Attached'}</td></tr>
|
|
`;
|
|
} else {
|
|
bodyRows += `
|
|
<tr><td style="padding:10px 0;font-weight:600;color:${accentColor};">Subject:</td><td style="padding:10px 0;color:#fff;">${contactSubject}</td></tr>
|
|
`;
|
|
}
|
|
|
|
const info = await transporter.sendMail({
|
|
from: fromEmail,
|
|
to: toEmail,
|
|
replyTo: `"${contactName}" <${contactEmail}>`,
|
|
subject: mailSubject,
|
|
text: `${formLabel}\n\nName: ${contactName}\nEmail: ${contactEmail}\nPhone: ${contactPhone}\nSubject/Type: ${contactSubject}\n\nMessage:\n${contactMessage}`,
|
|
html: `
|
|
<div style="font-family:'Segoe UI',Helvetica,Arial,sans-serif;background-color:#020710;color:#f8fafc;padding:40px 20px;max-width:650px;margin:0 auto;border-radius:16px;border:1px solid #1e293b;">
|
|
<div style="text-align:center;padding-bottom:24px;border-bottom:1px solid #334155;">
|
|
<h2 style="color:${accentColor};font-size:24px;margin:0;font-weight:700;">Cavin Infotech</h2>
|
|
<p style="color:#94a3b8;font-size:14px;margin-top:6px;">${formLabel}</p>
|
|
</div>
|
|
<div style="padding:24px 0;">
|
|
<table style="width:100%;border-collapse:collapse;font-size:15px;">${bodyRows}</table>
|
|
${contactMessage ? `<div style="margin-top:24px;padding:20px;background:#0b1528;border-left:4px solid ${accentColor};border-radius:8px;"><p style="margin:0;color:#f1f5f9;font-size:15px;line-height:1.6;white-space:pre-line;">${contactMessage}</p></div>` : ''}
|
|
</div>
|
|
<div style="text-align:center;padding-top:20px;border-top:1px solid #334155;color:#64748b;font-size:12px;">
|
|
Submitted on ${new Date().toLocaleString()} from Cavin Infotech Website
|
|
</div>
|
|
</div>
|
|
`
|
|
});
|
|
|
|
return res.status(200).json({ success: true, messageId: info.messageId, message: 'Message sent via SMTP!' });
|
|
} catch (smtpErr) {
|
|
console.error('SMTP Send Error:', smtpErr);
|
|
return res.status(500).json({ error: `SMTP Send Error: ${smtpErr.message}` });
|
|
}
|
|
}
|
|
|
|
// 2. Fallback to EmailJS API if SMTP env vars are not set
|
|
const serviceId = process.env.EMAILJS_SERVICE_ID || 'vishva_cavintest';
|
|
const publicKey = process.env.EMAILJS_PUBLIC_KEY || 'YOUR_EMAILJS_PUBLIC_KEY';
|
|
const templateId = process.env.EMAILJS_TEMPLATE_ID_STRATEGY || 'YOUR_EMAILJS_TEMPLATE_ID_STRATEGY';
|
|
|
|
try {
|
|
const response = await fetch('https://api.emailjs.com/api/v1.0/email/send', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
service_id: serviceId,
|
|
template_id: templateId,
|
|
user_id: publicKey,
|
|
template_params: {
|
|
name: contactName,
|
|
email: contactEmail,
|
|
phone: contactPhone,
|
|
interests: contactSubject,
|
|
message: contactMessage
|
|
}
|
|
}),
|
|
});
|
|
|
|
const data = await response.text();
|
|
if (!response.ok) {
|
|
return res.status(response.status).json({ error: data });
|
|
}
|
|
return res.status(200).json({ success: true, message: data });
|
|
} catch (error) {
|
|
return res.status(500).json({ error: error.message });
|
|
}
|
|
}
|