83 lines
2.8 KiB
JavaScript
83 lines
2.8 KiB
JavaScript
require('dotenv').config({ override: true });
|
|
const express = require('express');
|
|
const crypto = require('crypto');
|
|
const { generateInvoicePDF } = require('./pdfGenerator');
|
|
const { sendEmailWithAttachment } = require('./mailer');
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3000;
|
|
|
|
// Middleware to capture raw body for Shopify webhook HMAC verification
|
|
app.use(express.json({
|
|
verify: (req, res, buf) => {
|
|
req.rawBody = buf;
|
|
}
|
|
}));
|
|
|
|
// Function to verify Shopify Webhook
|
|
const verifyShopifyWebhook = (req, res, next) => {
|
|
const hmacHeader = req.get('X-Shopify-Hmac-Sha256');
|
|
const body = req.rawBody;
|
|
const secret = process.env.SHOPIFY_WEBHOOK_SECRET;
|
|
|
|
if (!hmacHeader || !body || !secret) {
|
|
return res.status(401).send('Webhook verification failed: Missing headers or secret.');
|
|
}
|
|
|
|
const generatedHash = crypto
|
|
.createHmac('sha256', secret)
|
|
.update(body, 'utf8')
|
|
.digest('base64');
|
|
|
|
if (generatedHash !== hmacHeader) {
|
|
return res.status(401).send('Webhook verification failed: Invalid HMAC.');
|
|
}
|
|
|
|
next();
|
|
};
|
|
|
|
// Webhook endpoint for Order Creation
|
|
app.post('/webhooks/orders/create', verifyShopifyWebhook, async (req, res) => {
|
|
const fs = require('fs');
|
|
const logMessage = `[${new Date().toISOString()}] Received webhook request\n`;
|
|
fs.appendFileSync('webhook.log', logMessage);
|
|
|
|
// Acknowledge receipt of the webhook immediately
|
|
res.status(200).send('Webhook received');
|
|
|
|
try {
|
|
const orderData = req.body;
|
|
const processMessage = `[${new Date().toISOString()}] Processing Order ${orderData.order_number}\n`;
|
|
fs.appendFileSync('webhook.log', processMessage);
|
|
|
|
// 1. Generate the PDF invoice
|
|
const pdfBuffer = await generateInvoicePDF(orderData);
|
|
|
|
// 2. Send the email with the attached PDF
|
|
const customerEmail = orderData.email || orderData.contact_email;
|
|
if (!customerEmail) {
|
|
const errorMsg = `[${new Date().toISOString()}] Order ${orderData.order_number} has no email address associated.\n`;
|
|
fs.appendFileSync('webhook.log', errorMsg);
|
|
return;
|
|
}
|
|
|
|
await sendEmailWithAttachment(
|
|
customerEmail,
|
|
orderData,
|
|
pdfBuffer
|
|
);
|
|
|
|
const successMsg = `[${new Date().toISOString()}] Successfully processed and sent email for Order ${orderData.order_number}\n`;
|
|
fs.appendFileSync('webhook.log', successMsg);
|
|
|
|
} catch (error) {
|
|
const errorMsg = `[${new Date().toISOString()}] Error processing order webhook: ${error.stack}\n`;
|
|
fs.appendFileSync('webhook.log', errorMsg);
|
|
console.error('Error processing order webhook:', error);
|
|
}
|
|
});
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`Shopify Invoice Email Plugin running on port ${PORT}`);
|
|
});
|