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} `; // Check if local logo exists for CID inline attachment const localLogoPath = path.join(__dirname, 'logo.png'); const logoExists = fs.existsSync(localLogoPath); // Use cid:store_logo in HTML - Gmail renders CID attachments correctly const logoImgTag = logoExists ? `rayaarishop` : `rayaarishop`; // --- 1. Generate Order Summary Rows HTML --- let orderRowsHtml = ''; if (orderData.line_items && orderData.line_items.length > 0) { orderData.line_items.forEach((item, index) => { const itemPrice = parseFloat(item.price).toFixed(2); const rowBg = index % 2 === 0 ? '#ffffff' : '#f8fafc'; orderRowsHtml += ` ${item.title || item.name} ${item.variant_title ? `
${item.variant_title}` : ''} ${item.quantity} ${currencySymbol}${itemPrice} `; }); } // --- 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
${logoImgTag}

New Order: #${orderNumber}

You've received the following order from ${orderData.billing_address ? `${orderData.billing_address.first_name || ''} ${orderData.billing_address.last_name || ''}`.trim() : (orderData.contact_email || 'a customer')}:

${orderData.order_status_url ? `[Order #${orderNumber}]` : `[Order #${orderNumber}]` } (${new Date(orderData.created_at || Date.now()).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })})

${orderRowsHtml}
Product Quantity Price
${taxRow}
Total ${currencySymbol}${total}

Customer information

Billing address ${billingAddressHtml} Payment method ${paymentMethod} Shipping method ${shippingMethod}
`; // Build attachments array - always include PDF, add logo as CID inline if it exists const attachments = [ { filename: `Invoice_${orderNumber}.pdf`, content: pdfBuffer, contentType: 'application/pdf' } ]; if (logoExists) { attachments.push({ filename: 'logo.png', path: localLogoPath, cid: 'store_logo' // Referenced in HTML as src="cid:store_logo" }); } 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 }; 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 };