const nodemailer = require('nodemailer'); const fs = require('fs'); const path = require('path'); /** * 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} `; // Load logo as base64 so it always displays in Gmail (no external URL blocking) const localLogoPath = path.join(__dirname, 'logo.png'); let logoBase64 = ''; let logoMimeType = 'image/png'; if (fs.existsSync(localLogoPath)) { logoBase64 = fs.readFileSync(localLogoPath).toString('base64'); } // --- 1. Generate Order Summary Rows HTML --- let orderRowsHtml = ''; if (orderData.line_items && orderData.line_items.length > 0) { orderData.line_items.forEach(item => { // Shopify stores product image under item.image (object with src) or item.featured_image.url const itemImageUrl = (item.image && item.image.src) || (item.image && typeof item.image === 'string' ? 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 };