8
n8n 中文网amn8n.com

证书生成器

高级

这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 25 个节点。主要使用 If, Code, Gmail, Slack, Webhook 等节点。 使用VerifiEmail和HTMLcsstoImg生成证书并通过Gmail发送

前置要求
  • Google 账号和 Gmail API 凭证
  • Slack Bot Token 或 Webhook URL
  • HTTP Webhook 端点(n8n 会自动生成)
  • Google Sheets API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "",
  "meta": {
    "instanceId": ""
  },
  "name": "证书生成器",
  "tags": [
    {
      "id": "CWzMtsCN0QfPR9PC",
      "name": "certificates",
      "createdAt": "2025-10-04T15:28:20.021Z",
      "updatedAt": "2025-10-04T15:28:20.021Z"
    },
    {
      "id": "qFR253LK8bI8GX4z",
      "name": "automation",
      "createdAt": "2025-10-04T15:28:20.027Z",
      "updatedAt": "2025-10-04T15:28:20.027Z"
    }
  ],
  "nodes": [
    {
      "id": "8aef6c7c-9dfd-483b-9b66-ee9a21ad0e3b",
      "name": "凭据设置指南",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3024,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 452,
        "height": 856,
        "content": "## 🔧 需要设置凭据"
      },
      "typeVersion": 1
    },
    {
      "id": "713712a6-27e5-482b-8994-eae001ab2785",
      "name": "Webhook 信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2512,
        64
      ],
      "parameters": {
        "color": 7,
        "width": 444,
        "height": 628,
        "content": "## 📥 WEBHOOK 触发器"
      },
      "typeVersion": 1
    },
    {
      "id": "a8b8e036-c01d-4091-b817-43611a1e2643",
      "name": "证书请求 Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -2192,
        544
      ],
      "webhookId": "certificate-generator",
      "parameters": {
        "path": "certificate-generator",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2
    },
    {
      "id": "3129040e-f390-4661-b17a-32b5c029cd8b",
      "name": "电子邮件验证信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2016,
        144
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "height": 548,
        "content": "## 📧 电子邮件验证步骤"
      },
      "typeVersion": 1
    },
    {
      "id": "5c1071ea-cc45-49b2-9498-083d3a09508b",
      "name": "验证逻辑",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1584,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 360,
        "height": 596,
        "content": "## ✅ 验证检查点"
      },
      "typeVersion": 1
    },
    {
      "id": "745c8af8-c38e-4257-968d-c8abeb30e5d3",
      "name": "数据合并信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1184,
        -32
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "height": 716,
        "content": "## 🔄 合并 WEBHOOK + 电子邮件数据"
      },
      "typeVersion": 1
    },
    {
      "id": "99566da7-4b33-4df0-a280-5a5db861bf13",
      "name": "HTML 生成信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -768,
        -48
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "height": 724,
        "content": "## 🎨 HTML 证书生成器"
      },
      "typeVersion": 1
    },
    {
      "id": "d2f582b7-9d23-43b9-bc05-e50f96ad122f",
      "name": "生成 HTML 证书",
      "type": "n8n-nodes-base.code",
      "position": [
        -640,
        528
      ],
      "parameters": {
        "jsCode": "// Certificate HTML Generator\nconst items = $input.all();\n\nreturn items.map(item => {\n  const data = item.json;\n  \n  // Generate unique certificate ID if not provided\n  const certId = data.certificateId || `CERT-${Date.now()}-${Math.random().toString(36).substr(2, 9).toUpperCase()}`;\n  \n  // Format date nicely\n  const certDate = new Date(data.date).toLocaleDateString('en-US', {\n    year: 'numeric',\n    month: 'long',\n    day: 'numeric'\n  });\n  \n  // HTML Template with inline CSS\n  const htmlContent = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Certificate of Completion</title>\n    <style>\n        @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=Montserrat:wght@300;400;600&display=swap');\n        \n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n        \n        body {\n            width: 1200px;\n            height: 850px;\n            font-family: 'Montserrat', sans-serif;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            padding: 40px;\n        }\n        \n        .certificate {\n            background: white;\n            width: 100%;\n            height: 100%;\n            border: 20px solid #f8f9fa;\n            box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n            position: relative;\n            padding: 60px 80px;\n            display: flex;\n            flex-direction: column;\n            justify-content: space-between;\n        }\n        \n        .certificate::before {\n            content: '';\n            position: absolute;\n            top: 35px;\n            left: 35px;\n            right: 35px;\n            bottom: 35px;\n            border: 3px solid #667eea;\n            pointer-events: none;\n        }\n        \n        .header {\n            text-align: center;\n            margin-bottom: 20px;\n        }\n        \n        .logo {\n            width: 80px;\n            height: 80px;\n            margin: 0 auto 15px;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            border-radius: 50%;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            color: white;\n            font-size: 36px;\n            font-weight: bold;\n        }\n        \n        .title {\n            font-family: 'Playfair Display', serif;\n            font-size: 48px;\n            font-weight: 700;\n            color: #2d3748;\n            letter-spacing: 2px;\n            margin-bottom: 10px;\n        }\n        \n        .subtitle {\n            font-size: 18px;\n            color: #718096;\n            text-transform: uppercase;\n            letter-spacing: 3px;\n            font-weight: 300;\n        }\n        \n        .content {\n            text-align: center;\n            flex-grow: 1;\n            display: flex;\n            flex-direction: column;\n            justify-content: center;\n        }\n        \n        .presented-to {\n            font-size: 16px;\n            color: #718096;\n            text-transform: uppercase;\n            letter-spacing: 2px;\n            margin-bottom: 20px;\n        }\n        \n        .recipient-name {\n            font-family: 'Playfair Display', serif;\n            font-size: 56px;\n            font-weight: 700;\n            color: #667eea;\n            margin-bottom: 30px;\n            padding-bottom: 15px;\n            border-bottom: 3px solid #e2e8f0;\n            display: inline-block;\n            min-width: 500px;\n        }\n        \n        .description {\n            font-size: 18px;\n            color: #4a5568;\n            line-height: 1.8;\n            margin-bottom: 25px;\n            max-width: 700px;\n            margin-left: auto;\n            margin-right: auto;\n        }\n        \n        .course-name {\n            font-weight: 600;\n            color: #2d3748;\n            font-size: 24px;\n            margin: 20px 0;\n        }\n        \n        .footer {\n            display: flex;\n            justify-content: space-between;\n            align-items: flex-end;\n            margin-top: 40px;\n        }\n        \n        .signature-block {\n            text-align: center;\n            flex: 1;\n        }\n        \n        .signature-line {\n            border-top: 2px solid #2d3748;\n            width: 250px;\n            margin: 0 auto 10px;\n            padding-top: 5px;\n        }\n        \n        .signature-name {\n            font-weight: 600;\n            color: #2d3748;\n            font-size: 16px;\n            margin-bottom: 5px;\n        }\n        \n        .signature-title {\n            font-size: 14px;\n            color: #718096;\n        }\n        \n        .date-block {\n            text-align: center;\n        }\n        \n        .date-label {\n            font-size: 12px;\n            color: #718096;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            margin-bottom: 5px;\n        }\n        \n        .date-value {\n            font-weight: 600;\n            color: #2d3748;\n            font-size: 16px;\n        }\n        \n        .cert-id {\n            position: absolute;\n            bottom: 15px;\n            right: 25px;\n            font-size: 10px;\n            color: #a0aec0;\n            letter-spacing: 1px;\n        }\n        \n        .badge {\n            position: absolute;\n            top: 50px;\n            right: 60px;\n            width: 100px;\n            height: 100px;\n            background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);\n            border-radius: 50%;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            box-shadow: 0 4px 15px rgba(255, 215, 0, 0.4);\n        }\n        \n        .badge::before {\n            content: '★';\n            font-size: 50px;\n            color: white;\n        }\n    </style>\n</head>\n<body>\n    <div class=\"certificate\">\n        <div class=\"badge\"></div>\n        \n        <div class=\"header\">\n            <div class=\"logo\">C</div>\n            <h1 class=\"title\">Certificate of Completion</h1>\n            <p class=\"subtitle\">This certifies that</p>\n        </div>\n        \n        <div class=\"content\">\n            <div class=\"recipient-name\">${data.name}</div>\n            \n            <p class=\"description\">\n                has successfully completed the course\n            </p>\n            \n            <div class=\"course-name\">${data.course}</div>\n            \n            ${data.duration ? `<p class=\"description\" style=\"margin-top: 10px; font-size: 16px;\">Duration: ${data.duration}</p>` : ''}\n        </div>\n        \n        <div class=\"footer\">\n            <div class=\"signature-block\">\n                <div class=\"signature-line\"></div>\n                <div class=\"signature-name\">${data.instructor || 'Program Director'}</div>\n                <div class=\"signature-title\">Instructor</div>\n            </div>\n            \n            <div class=\"date-block\">\n                <div class=\"date-label\">Date of Completion</div>\n                <div class=\"date-value\">${certDate}</div>\n            </div>\n        </div>\n        \n        <div class=\"cert-id\">Certificate ID: ${certId}</div>\n    </div>\n</body>\n</html>\n  `;\n  \n  return {\n    json: {\n      ...data,\n      certificateId: certId,\n      html: htmlContent,\n      formattedDate: certDate\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "9e764afe-be0f-4a6a-b5fc-4e2213353ae4",
      "name": "图像转换信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        -16
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "height": 704,
        "content": "## 图像转换"
      },
      "typeVersion": 1
    },
    {
      "id": "edac6e11-432b-42f2-9128-b39d4585bd5b",
      "name": "电子邮件发送信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "height": 808,
        "content": "## 证书电子邮件发送"
      },
      "typeVersion": 1
    },
    {
      "id": "7acdd47b-7014-4e0f-8b44-5acf326412be",
      "name": "发送证书电子邮件",
      "type": "n8n-nodes-base.gmail",
      "position": [
        288,
        528
      ],
      "webhookId": "",
      "parameters": {
        "sendTo": "={{ $('Code in JavaScript').item.json.email }}",
        "message": "=<!DOCTYPE html>\n<html>\n<head>\n    <style>\n        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 0; }\n        .container { max-width: 600px; margin: 0 auto; }\n        .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); \n                  color: white; padding: 40px 20px; text-align: center; }\n        .header h1 { margin: 0; font-size: 28px; }\n        .content { background: #f8f9fa; padding: 40px 30px; }\n        .content p { margin: 15px 0; }\n        .course-box { background: white; border-left: 4px solid #667eea; \n                      padding: 20px; margin: 25px 0; border-radius: 5px; }\n        .course-box h2 { color: #667eea; margin: 0 0 10px 0; font-size: 22px; }\n        .button { background: #667eea; color: white; padding: 15px 30px; \n                  text-decoration: none; border-radius: 5px; display: inline-block; \n                  margin: 20px 0; font-weight: bold; }\n        .button:hover { background: #5568d3; }\n        .details { background: white; padding: 20px; border-radius: 5px; margin: 20px 0; }\n        .details ul { list-style: none; padding: 0; }\n        .details li { padding: 8px 0; border-bottom: 1px solid #e2e8f0; }\n        .details li:last-child { border-bottom: none; }\n        .details strong { color: #667eea; }\n        .footer { text-align: center; padding: 30px 20px; color: #718096; font-size: 14px; }\n        .footer p { margin: 5px 0; }\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <div class=\"header\">\n            <h1>🎉 Congratulations, {{ $('Generate HTML Certificate').item.json.name }} !</h1>\n            <p style=\"margin: 10px 0 0 0; font-size: 16px;\">You've successfully completed your course</p>\n        </div>\n        \n        <div class=\"content\">\n            <p>We're thrilled to celebrate your achievement! You have successfully completed:</p>\n            \n            <div class=\"course-box\">\n                <h2>{{ $('Generate HTML Certificate').item.json.course }}</h2>\n                <p style=\"margin: 0; color: #718096;\">Completion Date: {{ $('Generate HTML Certificate').item.json.formattedDate }}</p>\n            </div>\n            \n            <p>Your certificate is ready and available for download. Share your accomplishment with your professional network!</p>\n            \n            <div style=\"text-align: center;\">\n                <a href=\"{{ $json.image_url }}\" class=\"button\">📥 Download Certificate</a>\n            </div>\n            \n            <div class=\"details\">\n                <p><strong>📋 Certificate Details:</strong></p>\n                <ul>\n                    <li><strong>Certificate ID:</strong>{{ $('Generate HTML Certificate').item.json.certificateId }} </li>\n                    <li><strong>Recipient:</strong>{{ $('Generate HTML Certificate').item.json.name }} </li>\n                    <li><strong>Course:</strong> {{ $('Generate HTML Certificate').item.json.course }}</li>\n                    <li><strong>Completion Date:</strong> {{ $('Generate HTML Certificate').item.json.formattedDate }}</li>\n                    {{ $json.duration ? '<li><strong>Duration:</strong> ' + $json.duration + '</li>' : '' }}\n                    {{ $json.instructor ? '<li><strong>Instructor:</strong> ' + $json.instructor + '</li>' : '' }}\n                </ul>\n            </div>\n            \n            <p><strong>💼 Share Your Success:</strong></p>\n            <p>Don't forget to add this certificate to your LinkedIn profile and share it with your network to showcase your new skills!</p>\n            \n            <p style=\"margin-top: 30px; color: #718096; font-size: 14px;\">If you have any questions about your certificate, please don't hesitate to reach out to our support team.</p>\n        </div>\n        \n        <div class=\"footer\">\n            <p><strong>Thank you for learning with us!</strong></p>\n            <p>© 2025 Your Organization. All rights reserved.</p>\n            <p style=\"font-size: 12px; margin-top: 15px;\">Certificate verification available at: yoursite.com/verify</p>\n        </div>\n    </div>\n</body>\n</html>",
        "options": {},
        "subject": "🎓 Congratulations! Your Certificate of Completion"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "",
          "name": "Gmail OAuth2"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "5820e8bb-2f26-4d04-8445-61ea99902d35",
      "name": "数据库记录信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        592,
        -176
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "height": 864,
        "content": "## GOOGLE SHEETS 记录"
      },
      "typeVersion": 1
    },
    {
      "id": "37b407ee-9362-402a-b708-5c821e1e1116",
      "name": "记录到 Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        752,
        528
      ],
      "parameters": {
        "columns": {
          "value": {
            "Email": "={{ $('Generate HTML Certificate').item.json.email }}",
            "Course": "={{ $('Generate HTML Certificate').item.json.course }}",
            "Status": "Sent",
            "Duration": "={{ $('Generate HTML Certificate').item.json.duration }}",
            "Instructor": "={{ $('Generate HTML Certificate').item.json.instructor }}",
            "Generated At": "={{ $now.toISO() }}",
            "Certificate ID": "={{ $('Generate HTML Certificate').item.json.certificateId }}",
            "Recipient Name": "={{ $('Generate HTML Certificate').item.json.name }}",
            "Certificate URL": "={{ $('HTML/CSS to Image').item.json.image_url }}",
            "Completion Date ": "={{ $('Generate HTML Certificate').item.json.date }}"
          },
          "schema": [
            {
              "id": "Certificate ID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Certificate ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Recipient Name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Recipient Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Course",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Course",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Completion Date ",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Completion Date ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Generated At",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Generated At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Certificate URL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Certificate URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Instructor",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Instructor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Duration",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Duration",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Certificate ID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultUrl": "",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultUrl": "",
          "cachedResultName": "Certificates Log"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "",
          "name": "Google Sheets OAuth2"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "559bc397-1e64-4f9e-91e0-69f01a2de564",
      "name": "成功响应信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        352
      ],
      "parameters": {
        "color": 7,
        "width": 716,
        "height": 624,
        "content": "## ⚠️ 推荐补充"
      },
      "typeVersion": 1
    },
    {
      "id": "bd541a23-e982-4b64-82e2-30aea3e7601d",
      "name": "错误处理信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2032,
        1088
      ],
      "parameters": {
        "color": 7,
        "width": 472,
        "height": 564,
        "content": "## ⚠️ 错误处理"
      },
      "typeVersion": 1
    },
    {
      "id": "429a6ac5-d269-4176-ac81-d65117df54dd",
      "name": "工作流出错时",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        -1680,
        1216
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "e3cc736c-3a91-42d5-9037-5ffcad3e8cab",
      "name": "格式化错误详情",
      "type": "n8n-nodes-base.code",
      "position": [
        -1472,
        1216
      ],
      "parameters": {
        "jsCode": "// Extract error information\nconst errorData = $input.first().json;\n\nreturn [{\n  json: {\n    errorMessage: errorData.error?.message || 'Unknown error occurred',\n    errorNode: errorData.node?.name || 'Unknown node',\n    timestamp: new Date().toISOString(),\n    workflowId: $workflow.id,\n    workflowName: $workflow.name,\n    executionId: $execution.id,\n    userData: {\n      name: errorData.json?.name || 'N/A',\n      email: errorData.json?.email || 'N/A',\n      course: errorData.json?.course || 'N/A'\n    },\n    fullError: JSON.stringify(errorData, null, 2)\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "c1ec5078-2bc7-4f7d-b413-fa0ca7691a15",
      "name": "发送Slack警报",
      "type": "n8n-nodes-base.slack",
      "notes": "Optional: Enable if you want Slack notifications",
      "disabled": true,
      "position": [
        -1280,
        1216
      ],
      "webhookId": "",
      "parameters": {
        "text": "=🚨 **Certificate Generation Failed**\n\n**Error:** {{ $json.errorMessage }}\n**Node:** {{ $json.errorNode }}\n**Time:** {{ $json.timestamp }}\n\n**User Details:**\n• Name: {{ $json.userData.name }}\n• Email: {{ $json.userData.email }}\n• Course: {{ $json.userData.course }}\n\n**Execution ID:** {{ $json.executionId }}\n**Workflow:** {{ $json.workflowName }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C12345",
          "cachedResultName": "alerts"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.2
    },
    {
      "id": "7d756f81-a0ac-4b11-bf07-dded65a5070d",
      "name": "工作流概览",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3376,
        800
      ],
      "parameters": {
        "color": 7,
        "width": 444,
        "height": 760,
        "content": "## 完整工作流结构"
      },
      "typeVersion": 1
    },
    {
      "id": "7c4dc0c1-ae2b-4985-91de-a40356e28158",
      "name": "测试说明",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2896,
        832
      ],
      "parameters": {
        "color": 7,
        "width": 568,
        "height": 856,
        "content": "## 🧪 测试您的工作流"
      },
      "typeVersion": 1
    },
    {
      "id": "b9b4ba6f-35ca-4733-9d0a-0e2a7da5b56e",
      "name": "HTML/CSS to Image",
      "type": "n8n-nodes-htmlcsstoimage.htmlCssToImage",
      "position": [
        -160,
        528
      ],
      "parameters": {
        "html_content": "={{ $json.html }}"
      },
      "credentials": {
        "htmlcsstoimgApi": {
          "id": "",
          "name": "Htmlcsstoimg API"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "de9c267d-d005-43d4-bbb3-c33370f9493a",
      "name": "Verifi Email",
      "type": "n8n-nodes-verifiemail.verifiEmail",
      "position": [
        -1872,
        544
      ],
      "parameters": {
        "email": "={{ $json.body.email }}"
      },
      "credentials": {
        "verifiEmailApi": {
          "id": "",
          "name": "VerifiEmail API"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "646e0a7b-2cdc-48c0-8f15-5b7755e9e484",
      "name": "条件判断",
      "type": "n8n-nodes-base.if",
      "position": [
        -1392,
        544
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a39497f8-8b8a-4b3a-bc5f-3e8738fa4cbb",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $('Certificate Request Webhook').item.json.body.name }}",
              "rightValue": ""
            },
            {
              "id": "37e0295c-18b2-4d3f-998b-e9d669dd90f7",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $('Certificate Request Webhook').item.json.body.course }}",
              "rightValue": ""
            },
            {
              "id": "6ecb1197-b460-402e-99a1-00edb0d5150c",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $('Certificate Request Webhook').item.json.body.date }}",
              "rightValue": ""
            },
            {
              "id": "3828fe0a-7c6a-449a-b380-c754717e0731",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.valid }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "9b7e5242-b3da-4552-b088-d585ffe7bcb0",
      "name": "停止并报错",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        -1040,
        784
      ],
      "parameters": {
        "errorMessage": "=\"Missing required fields: name, course, date, or valid email\""
      },
      "typeVersion": 1
    },
    {
      "id": "b57d3884-9846-4b1f-9b00-ec378ea386ac",
      "name": "JavaScript 代码",
      "type": "n8n-nodes-base.code",
      "position": [
        -1056,
        528
      ],
      "parameters": {
        "jsCode": "// Combine Webhook Data with Email Validation\n// Get the current item (from IF node - email validation data)\nconst emailData = $input.item.json;\n\n// Get the original webhook data from the first node\nconst webhookData = $('Certificate Request Webhook').first().json.body;\n\n// Combine everything\nreturn {\n  json: {\n    // Certificate data from webhook\n    name: webhookData.name,\n    course: webhookData.course,\n    date: webhookData.date,\n    email: webhookData.email,\n    instructor: webhookData.instructor || 'Program Director',\n    duration: webhookData.duration || '',\n    certificateId: webhookData.certificateId || '',\n    \n    // Email validation results (optional - for logging/debugging)\n    emailValidation: {\n      valid: emailData.valid,\n      provider: emailData.details.mx.provider,\n      rfcCompliant: emailData.details.rfcCompliant,\n      validMxRecord: emailData.details.validMxRecord,\n      disposable: emailData.details.disposable\n    }\n  }\n};"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Stop and Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verifi Email": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTML/CSS to Image": {
      "main": [
        [
          {
            "node": "Send Certificate Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On Workflow Error": {
      "main": [
        [
          {
            "node": "Format Error Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Generate HTML Certificate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Error Details": {
      "main": [
        [
          {
            "node": "Send Slack Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Certificate Email": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate HTML Certificate": {
      "main": [
        [
          {
            "node": "HTML/CSS to Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Certificate Request Webhook": {
      "main": [
        [
          {
            "node": "Verifi Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级 - 内容创作, 多模态 AI

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量25
分类2
节点类型11
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
Jitesh Dugar

Jitesh Dugar

@jiteshdugar

AI Automation Specialist - OpenAI, CRM & Automation Expert with a solid understanding of various tools that include Zapier, Make, Zoho CRM, Hubspot, Google Sheets, Airtable, Pipedrive, Google Analytics, and more.

外部链接
在 n8n.io 查看

分享此工作流