You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建表单实现邮件HTML组件选择、生成文件及邮件发送功能咨询

Solution: Build an Email Component Picker & HTML Generator Tool

Got it, here's a practical, step-by-step solution to build your tool that lets users select email components, generates the final HTML, and sends it directly to your inbox:


Step 1: Frontend Component Selection Interface

First, create a simple web form where users can pick, reorder, and submit their desired components. We'll use vanilla JS for drag-and-drop reordering (optional but user-friendly) and form submission.

<!DOCTYPE html>
<html>
<head>
    <title>Email Component Builder</title>
    <style>
        .component-option { margin: 10px 0; padding: 10px; border: 1px solid #ddd; border-radius: 4px; }
        #selected-components { margin: 20px 0; padding: 15px; border: 1px dashed #ccc; border-radius: 4px; }
        .selected-item { margin: 5px 0; padding: 8px; background: #f8f9fa; border-radius: 4px; cursor: grab; }
        .selected-item:active { cursor: grabbing; }
        button { padding: 10px 20px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; margin-right: 10px; }
        button:hover { background: #0056b3; }
    </style>
</head>
<body>
    <h2>Build Your Custom Email</h2>
    <div id="component-options">
        <div class="component-option">
            <input type="checkbox" value="hero" id="hero">
            <label for="hero">Hero Image Header</label>
        </div>
        <div class="component-option">
            <input type="checkbox" value="heading" id="heading">
            <label for="heading">Title Heading</label>
        </div>
        <div class="component-option">
            <input type="checkbox" value="paragraph" id="paragraph">
            <label for="paragraph">Text Paragraph</label>
        </div>
        <div class="component-option">
            <input type="checkbox" value="two-column-images" id="two-column">
            <label for="two-column">Two-Column Image Grid</label>
        </div>
        <div class="component-option">
            <input type="checkbox" value="button" id="button">
            <label for="button">CTA Button</label>
        </div>
    </div>
    <button onclick="addSelected()">Add Selected Components</button>
    <div id="selected-components">
        <h3>Selected Components (Drag to Reorder)</h3>
        <div id="components-list"></div>
    </div>
    <button onclick="submitBuild()">Generate & Send Email HTML</button>

    <script>
        let selectedComponents = [];

        function addSelected() {
            const checkboxes = document.querySelectorAll('.component-option input:checked');
            checkboxes.forEach(checkbox => {
                if (!selectedComponents.includes(checkbox.value)) {
                    selectedComponents.push(checkbox.value);
                    renderSelectedList();
                }
                checkbox.checked = false;
            });
        }

        function renderSelectedList() {
            const list = document.getElementById('components-list');
            list.innerHTML = '';
            selectedComponents.forEach((comp, index) => {
                const item = document.createElement('div');
                item.className = 'selected-item';
                item.draggable = true;
                item.dataset.index = index;
                item.textContent = getComponentName(comp);
                item.addEventListener('dragstart', handleDragStart);
                item.addEventListener('dragover', handleDragOver);
                item.addEventListener('drop', handleDrop);
                list.appendChild(item);
            });
        }

        // Drag-and-drop reorder logic
        let draggedIndex;
        function handleDragStart(e) {
            draggedIndex = parseInt(e.target.dataset.index);
        }
        function handleDragOver(e) {
            e.preventDefault();
        }
        function handleDrop(e) {
            e.preventDefault();
            const dropIndex = parseInt(e.target.dataset.index);
            const [draggedItem] = selectedComponents.splice(draggedIndex, 1);
            selectedComponents.splice(dropIndex, 0, draggedItem);
            renderSelectedList();
        }

        function getComponentName(key) {
            const names = {
                hero: 'Hero Image Header',
                heading: 'Title Heading',
                paragraph: 'Text Paragraph',
                'two-column-images': 'Two-Column Image Grid',
                button: 'CTA Button'
            };
            return names[key] || key;
        }

        function submitBuild() {
            if (selectedComponents.length === 0) {
                alert('Please select at least one component!');
                return;
            }
            fetch('/generate-email', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ components: selectedComponents })
            })
            .then(res => res.text())
            .then(msg => alert(msg))
            .catch(err => console.error(err));
        }
    </script>
</body>
</html>

Step 2: Backend (Node.js/Express) to Generate HTML & Send Email

Set up an Express server that receives the selected components, stitches your pre-written component code into a valid email HTML template, and sends it to your inbox using Nodemailer.

First, install dependencies:

npm init -y
npm install express nodemailer cors

Then create server.js:

const express = require('express');
const nodemailer = require('nodemailer');
const cors = require('cors');
const app = express();

app.use(cors());
app.use(express.json());
app.use(express.static('public')); // Serve the frontend HTML file

// Replace these with your pre-written, email-compatible component code
const componentLibrary = {
    hero: `
        <table width="100%" cellpadding="0" cellspacing="0" border="0">
            <tr>
                <td align="center" style="padding: 0;">
                    <img src="https://example.com/hero-default.jpg" alt="Hero Banner" width="600" style="max-width: 100%; height: auto;">
                </td>
            </tr>
        </table>
    `,
    heading: `
        <table width="100%" cellpadding="0" cellspacing="0" border="0">
            <tr>
                <td align="center" style="padding: 25px 0;">
                    <h1 style="font-family: Arial, sans-serif; color: #2d3748; font-size: 24px; margin: 0;">Your Custom Email Title</h1>
                </td>
            </tr>
        </table>
    `,
    paragraph: `
        <table width="100%" cellpadding="0" cellspacing="0" border="0">
            <tr>
                <td align="center" style="padding: 0 20px;">
                    <p style="font-family: Arial, sans-serif; color: #4a5568; line-height: 1.6; max-width: 600px; margin: 0 auto;">
                        This is your customizable paragraph text. Adjust it to fit your message, brand voice, and audience!
                    </p>
                </td>
            </tr>
        </table>
    `,
    'two-column-images': `
        <table width="100%" cellpadding="0" cellspacing="0" border="0">
            <tr>
                <td align="center" style="padding: 20px 0;">
                    <table width="600" cellpadding="0" cellspacing="0" border="0">
                        <tr>
                            <td width="50%" style="padding: 0 10px;">
                                <img src="https://example.com/image-1.jpg" alt="Product Image 1" width="280" style="max-width: 100%; height: auto;">
                            </td>
                            <td width="50%" style="padding: 0 10px;">
                                <img src="https://example.com/image-2.jpg" alt="Product Image 2" width="280" style="max-width: 100%; height: auto;">
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
    `,
    button: `
        <table width="100%" cellpadding="0" cellspacing="0" border="0">
            <tr>
                <td align="center" style="padding: 25px 0;">
                    <a href="https://example.com/cta-link" style="background: #3182ce; color: white; padding: 12px 28px; text-decoration: none; border-radius: 4px; font-family: Arial, sans-serif; font-size: 16px;">
                        Click Here to Take Action
                    </a>
                </td>
            </tr>
        </table>
    `
};

// Base email template (critical for cross-client compatibility)
const baseEmailTemplate = `
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Custom Generated Email</title>
        <style>
            body { margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f7fafc; }
            table { border-collapse: collapse; width: 100%; }
        </style>
    </head>
    <body>
        <table width="100%" cellpadding="0" cellspacing="0" border="0" bgcolor="#f7fafc">
            <tr>
                <td align="center" style="padding: 20px 0;">
                    <table width="600" cellpadding="0" cellspacing="0" border="0" bgcolor="#ffffff" style="border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
                        <!-- Insert selected components here -->
                        {{COMPONENTS}}
                    </table>
                </td>
            </tr>
        </table>
    </body>
    </html>
`;

// Configure Nodemailer (use your email provider's SMTP settings)
const transporter = nodemailer.createTransport({
    service: 'Gmail', // Swap with Outlook, SendGrid, or your provider
    auth: {
        user: 'your-email@example.com',
        pass: 'your-app-specific-password' // Use app password for Gmail (not your regular password)
    }
});

// Endpoint to handle component submission, HTML generation, and email sending
app.post('/generate-email', async (req, res) => {
    const { components } = req.body;
    if (!components || components.length === 0) {
        return res.status(400).send('No components selected');
    }

    // Stitch selected components into the base template
    const componentsHtml = components.map(comp => componentLibrary[comp] || '').join('');
    const finalEmailHtml = baseEmailTemplate.replace('{{COMPONENTS}}', componentsHtml);

    // Email options (send to yourself)
    const mailOptions = {
        from: 'Email Component Builder <your-email@example.com>',
        to: 'your-email@example.com',
        subject: 'New Custom Email HTML Ready',
        html: `<p>Here's the generated email HTML:</p><pre style="background: #f7fafc; padding: 10px; border-radius: 4px;">${finalEmailHtml}</pre>`,
        attachments: [
            {
                filename: 'custom-email.html',
                content: finalEmailHtml,
                contentType: 'text/html'
            }
        ]
    };

    try {
        await transporter.sendMail(mailOptions);
        res.send('Success! Your custom email HTML has been sent to your inbox.');
    } catch (error) {
        console.error('Email send error:', error);
        res.status(500).send('Oops, something went wrong. Please try again later.');
    }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
});

Step 3: Customization & Deployment Tips

  • Component Code: Replace the placeholder HTML in componentLibrary with your own email-optimized code (remember, emails rely on table layouts and inline styles for broad client support).
  • User Input: Extend the frontend form to let users customize component content (e.g., heading text, button URL, image sources) and pass those values to the backend for dynamic insertion.
  • Email Provider: For better deliverability, use a transactional email service like SendGrid or Mailgun instead of Gmail.
  • Deployment: Host the app on platforms like Heroku, Vercel, or Netlify so users can access it from anywhere.

How to Run Locally

  1. Save the frontend HTML as public/index.html
  2. Create server.js with the backend code
  3. Install dependencies and start the server:
    npm install
    node server.js
    
  4. Visit http://localhost:3000 in your browser to use the tool!

内容的提问来源于stack exchange,提问作者Pairtho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:36:35