Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const { sendZohoEmailRaw } = require('../../utils/zoho'); // adjust path
- const { z } = require('zod');
- // Zod schema за валидация
- const SendApplicationEmailSchema = z.object({
- recipients: z.array(z.object({
- email: z.string().email(),
- firstName: z.string(),
- lastName: z.string(),
- projectId: z.string()
- })).min(1),
- template: z.object({
- subject: z.string().min(1),
- content: z.string().min(1)
- }),
- mode: z.enum(['individual', 'bulk'])
- });
- async function sendApplicationEmail({ recipients, template, projectData }) {
- const formattedSubject = `[Pensa Club] ${template.subject}`;
- const formattedBody = `
- <html>
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- </head>
- <body style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 0; background: #f5f7fa;">
- <div style="max-width: 600px; margin: 0 auto; background: #ffffff;">
- <!-- Header -->
- <div style="
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- padding: 32px 24px;
- text-align: center;
- border-radius: 12px 12px 0 0;
- ">
- <div style="
- background: rgba(255, 255, 255, 0.15);
- backdrop-filter: blur(10px);
- border: 1px solid rgba(255, 255, 255, 0.2);
- border-radius: 50%;
- width: 80px;
- height: 80px;
- margin: 0 auto 16px auto;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 36px;
- color: white;
- ">
- 🚀
- </div>
- <h1 style="
- color: white;
- font-size: 28px;
- font-weight: 700;
- margin: 0 0 8px 0;
- text-shadow: 0 2px 4px rgba(0,0,0,0.1);
- ">
- Pensa Club
- </h1>
- <p style="
- color: rgba(255, 255, 255, 0.9);
- font-size: 16px;
- margin: 0;
- font-weight: 400;
- ">
- Initiative Platform
- </p>
- </div>
- <!-- Content -->
- <div style="padding: 40px 32px;">
- <div style="
- background: #f8fafc;
- border-left: 4px solid #667eea;
- padding: 20px;
- border-radius: 8px;
- margin-bottom: 32px;
- ">
- <div style="
- color: #2d3748;
- font-size: 18px;
- font-weight: 600;
- margin-bottom: 12px;
- ">
- ${template.subject}
- </div>
- </div>
- <div style="
- color: #4a5568;
- font-size: 16px;
- line-height: 1.6;
- white-space: pre-wrap;
- margin-bottom: 32px;
- ">
- ${template.content}
- </div>
- <!-- Project Info -->
- ${projectData ? `
- <div style="
- background: linear-gradient(135deg, #e6fffa 0%, #f0fff4 100%);
- border: 1px solid #9ae6b4;
- border-radius: 12px;
- padding: 20px;
- margin-bottom: 32px;
- ">
- <h3 style="
- color: #2d3748;
- font-size: 16px;
- font-weight: 600;
- margin: 0 0 12px 0;
- ">
- 📋 Project Information
- </h3>
- <p style="
- color: #4a5568;
- font-size: 14px;
- margin: 0;
- line-height: 1.5;
- ">
- <strong>Project:</strong> ${projectData.title || projectData.id}<br>
- ${projectData.description ? `<strong>Description:</strong> ${projectData.description}` : ''}
- </p>
- </div>
- ` : ''}
- <!-- CTA -->
- <div style="text-align: center; margin: 32px 0;">
- <a href="${process.env.FRONTEND_SERVER}" style="
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- color: white;
- padding: 14px 28px;
- border-radius: 8px;
- text-decoration: none;
- font-weight: 600;
- font-size: 16px;
- display: inline-block;
- box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
- ">
- 🌐 Visit Pensa Club
- </a>
- </div>
- </div>
- <!-- Footer -->
- <div style="
- background: #f7fafc;
- padding: 24px 32px;
- text-align: center;
- border-top: 1px solid #e2e8f0;
- border-radius: 0 0 12px 12px;
- ">
- <p style="
- color: #718096;
- font-size: 14px;
- margin: 0 0 8px 0;
- ">
- This email was sent from <strong>Pensa Club</strong> Initiative Platform
- </p>
- <p style="
- color: #a0aec0;
- font-size: 12px;
- margin: 0;
- ">
- If you have any questions, please contact us at
- </p>
- </div>
- </div>
- </body>
- </html>
- `;
- // Изпрати до всички recipients
- const results = [];
- for (const recipient of recipients) {
- try {
- const data = {
- toAddress: recipient.email,
- subject: formattedSubject,
- content: formattedBody,
- };
- const result = await sendZohoEmailRaw(data);
- results.push({
- success: true,
- recipient: recipient.email,
- result
- });
- } catch (error) {
- console.error(`Failed to send email to ${recipient.email}:`, error);
- results.push({
- success: false,
- recipient: recipient.email,
- error: error.message
- });
- }
- }
- return results;
- }
- export default async function handler(req, res) {
- if (req.method !== 'POST') {
- return res.status(405).json({ error: 'Method not allowed' });
- }
- try {
- // Валидация с Zod
- const validatedData = SendApplicationEmailSchema.parse(req.body);
- const results = await sendApplicationEmail({
- recipients: validatedData.recipients,
- template: validatedData.template,
- projectData: req.body.projectData // optional
- });
- const successCount = results.filter(r => r.success).length;
- const errorCount = results.filter(r => !r.success).length;
- res.status(200).json({
- success: true,
- results,
- summary: {
- total: results.length,
- successful: successCount,
- failed: errorCount
- }
- });
- } catch (error) {
- console.error('Send email error:', error);
- if (error instanceof z.ZodError) {
- return res.status(400).json({
- success: false,
- error: 'Validation failed',
- details: error.errors
- });
- }
- res.status(500).json({
- success: false,
- error: 'Failed to send emails'
- });
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment