const nodemailer = require('nodemailer'); /** * Sends a premium custom email with the PDF attachment. * @param {string} toEmail - The recipient's email address * @param {Object} orderData - The Shopify order payload * @param {Buffer} pdfBuffer - The PDF data buffer */ const sendEmailWithAttachment = async (toEmail, orderData, pdfBuffer) => { const transporter = nodemailer.createTransport({ host: process.env.SMTP_HOST, port: Number(process.env.SMTP_PORT) || 465, secure: process.env.SMTP_SECURE === 'true', auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS, }, tls: { rejectUnauthorized: false } }); const orderNumber = orderData.order_number || orderData.name; const currencySymbol = orderData.currency === 'INR' ? 'Rs. ' : `${orderData.currency} `; // --- 1. Generate Order Summary Rows HTML --- let orderRowsHtml = ''; if (orderData.line_items && orderData.line_items.length > 0) { orderData.line_items.forEach(item => { const itemImageUrl = item.image || (item.featured_image && item.featured_image.url) || ''; const imageHtml = itemImageUrl ? ` ${item.title} ` : `
`; const variantText = item.variant_title ? `${item.variant_title}` : ''; const itemTotal = (parseFloat(item.price) * item.quantity).toFixed(2); orderRowsHtml += ` ${imageHtml} ${item.title || item.name} × ${item.quantity} ${variantText} ${currencySymbol}${itemTotal} `; }); } // --- 2. Calculate Totals --- const subtotal = parseFloat(orderData.subtotal_price).toFixed(2); const shipping = parseFloat(orderData.total_shipping_price_set?.shop_money?.amount || 0).toFixed(2); const taxes = parseFloat(orderData.total_tax || 0).toFixed(2); const total = parseFloat(orderData.total_price).toFixed(2); let taxRow = ''; if (parseFloat(taxes) > 0) { taxRow = ` Taxes ${currencySymbol}${taxes} `; } // --- 3. Billing Address Details HTML --- const billing = orderData.billing_address || {}; let billingAddressHtml = ''; if (billing.first_name || billing.last_name) { billingAddressHtml += `${billing.first_name || ''} ${billing.last_name || ''}
`; } if (billing.address1) billingAddressHtml += `${billing.address1}
`; if (billing.address2) billingAddressHtml += `${billing.address2}
`; if (billing.city || billing.province || billing.zip) { billingAddressHtml += `${billing.city || ''} ${billing.province || ''} ${billing.zip || ''}
`; } if (billing.country) billingAddressHtml += `${billing.country}
`; if (billing.phone || orderData.phone) { billingAddressHtml += `${billing.phone || orderData.phone}`; } const paymentMethod = orderData.gateway || 'Request Quote'; const shippingMethod = orderData.shipping_lines?.[0]?.title || 'Economy'; // --- 4. Beautiful Responsive HTML Template --- const htmlTemplate = ` Order Confirmation
${orderData.order_status_url ? ` ` : ''}
rayaarishop Order #${orderNumber}

Thank you for your order!

We're getting your order ready to be shipped. We have attached your custom PDF invoice directly to this email.

View your order or Visit our store

Order summary

${orderRowsHtml}
${taxRow}
Subtotal ${currencySymbol}${subtotal}
Shipping ${currencySymbol}${shipping}
Total ${currencySymbol}${total} ${orderData.currency}

Customer information

Billing address ${billingAddressHtml} Payment method ${paymentMethod} Shipping method ${shippingMethod}
`; const mailOptions = { from: `"${process.env.SHOP_NAME || 'Your Store'}" <${process.env.SMTP_FROM_EMAIL}>`, to: toEmail, subject: `Invoice for your order #${orderNumber}`, text: `Thank you for your order! Attached is the invoice for order #${orderNumber}.`, html: htmlTemplate, attachments: [ { filename: `Invoice_${orderNumber}.pdf`, content: pdfBuffer, contentType: 'application/pdf' } ] }; try { const info = await transporter.sendMail(mailOptions); console.log(`Email sent: ${info.messageId}`); return info; } catch (error) { console.error('Error sending email:', error); throw error; } }; module.exports = { sendEmailWithAttachment };