
2025 Nov - Quality Assurance: review newsletter before sending to subscribers (LLM Judge)
説明
Categories
🤖 AI & Machine Learning
Nodes Used
n8n-nodes-base.ifn8n-nodes-base.setn8n-nodes-base.setn8n-nodes-base.waitn8n-nodes-base.gmailn8n-nodes-base.gmailn8n-nodes-base.gmailn8n-nodes-base.gmailn8n-nodes-base.stickyNoten8n-nodes-base.stickyNote
Price無料
Views0
最終更新11/28/2025
workflow.json
{
"id": "BdyzMyNpnkpiJvc9",
"meta": {
"instanceId": "4e839a74f9cee9cae404b83e2a9088ce8b38f21e009880813cc56e5bb8aa4410",
"templateCredsSetupCompleted": true
},
"name": "2025 Nov - Quality Assurance: review newsletter before sending to subscribers (LLM Judge)",
"tags": [],
"nodes": [
{
"id": "d2d3baf1-6092-4108-8707-80d7e5cd1f88",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2384,
-352
],
"parameters": {
"color": 4,
"width": 256,
"height": 304,
"content": "## Send Prepared Newsletter to LLM Judge's mailbox.\nSends the newsletter to the inbox of the LLM Judge so it can grab the rendered version of it."
},
"typeVersion": 1
},
{
"id": "035aaeaf-eff9-4cf2-819d-6245a8e0875f",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
1376,
16
],
"parameters": {
"width": 624,
"height": 944,
"content": "## Newsletter expected structure\n\n"
},
"typeVersion": 1
},
{
"id": "e78daaf2-2ca8-4106-9ba6-67b2d0c8521f",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
1376,
-1376
],
"parameters": {
"width": 624,
"height": 1360,
"content": "## Newsletter Quality Assurance with LLM Judge\n\nThis sub-workflow validates newsletter quality before sending to customers. It's triggered by the main newsletter workflow and acts as an automated quality gate to catch data issues, broken layouts, or missing content.\n\n## Who's it for\n\nE-commerce teams who want to automate newsletter quality checks and prevent broken or incomplete emails from reaching customers. Perfect for ensuring consistent brand quality without manual review.\n\n## How it works\n\n1. **Receives newsletter HTML** - Triggered by parent workflow with the generated newsletter content\n2. **Sends to test inbox** - Delivers newsletter to LLM Judge's Gmail inbox to validate actual rendering\n3. **Retrieves rendered email** - Fetches the email back from Gmail to analyze how it actually renders (catches Gmail-specific issues)\n4. **AI-powered validation** - GPT-5 analyzes the newsletter against quality criteria:\n - Verifies all 6 product cards have images, prices, and descriptions\n - Checks layout integrity and date range formatting\n - Detects broken images or unprocessed template variables\n - Validates sale prices are lower than original prices\n5. **Decision gate** - Based on Judge's verdict:\n - **PASS**: Returns approval to parent workflow → sends to customers\n - **BLOCK**: Alerts admin via email → requires human review\n\n## Set up steps\n\n**Setup time: ~5 minutes**\n\n1. Connect your **Gmail account** for sending test emails\n2. Update the **Judge's email address** in \"Send newsletter to LLM Judge\" node\n3. Update the **admin alert email** in error handling nodes\n4. Connect your **OpenAI API** credentials (GPT-5 recommended for heavy HTML processing)\n5. (Optional) Adjust quality thresholds in the Judge's system prompt\n\n## Requirements\n\n- Gmail account for test sends and retrieving rendered emails\n- OpenAI API key (GPT-5 recommended)\n- Parent workflow that passes newsletter HTML content\n\n## How to customize\n\n- **Adjust validation strictness**: Modify the Judge's system prompt to change what triggers BLOCK vs PASS\n- **Change product count**: Update prompt if your newsletters have different numbers of products\n- **Add custom checks**: Extend the system prompt with brand-specific validation rules\n- **Modify alert recipients**: Update email addresses in error handling nodes\n\n💡 **Pro tip**: The workflow validates the actual Gmail-rendered version to catch image loading issues and ensure consistent customer experience."
},
"typeVersion": 1
},
{
"id": "b75572bd-3c93-4eed-8afe-8a8645a713c2",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
4864,
-192
],
"parameters": {
"width": 320,
"height": 144,
"content": "## Questions or Feedback?\n\n📧 [email protected] \n💼 [linkedin.com/in/emirbelkahia](https://www.linkedin.com/in/emirbelkahia/)"
},
"typeVersion": 1
},
{
"id": "f6e0d539-bfa9-4c95-b1ee-940396853f95",
"name": "Send newsletter to LLM Judge",
"type": "n8n-nodes-base.gmail",
"position": [
2464,
-16
],
"webhookId": "dfc14f6f-b99c-458e-9e8b-9b5b7212e23e",
"parameters": {
"sendTo": "[email protected]",
"message": "={{ $json.html }}",
"options": {
"appendAttribution": false
},
"subject": "=FOR REVIEW BY JUDGE - Dogtreats - Promos of the week"
},
"credentials": {
"gmailOAuth2": {
"id": "3IbPKCEy8B41xC1R",
"name": "Gmail account 3"
}
},
"typeVersion": 2.1
},
{
"id": "ade87ac8-112f-4db3-988b-cde23037107d",
"name": "Get the newsletter",
"type": "n8n-nodes-base.gmail",
"position": [
2928,
-16
],
"webhookId": "a17ce0fc-74e9-4d53-bd09-3c91c094bcd2",
"parameters": {
"simple": false,
"options": {},
"messageId": "={{ $('Send newsletter to LLM Judge').item.json.id }}",
"operation": "get"
},
"credentials": {
"gmailOAuth2": {
"id": "3IbPKCEy8B41xC1R",
"name": "Gmail account 3"
}
},
"typeVersion": 2.1
},
{
"id": "425491b5-65f9-4f0f-9f64-9e6c1dac568a",
"name": "Give the email some time to arrive",
"type": "n8n-nodes-base.wait",
"position": [
2704,
-16
],
"webhookId": "fbfe4960-1d76-483a-abef-0b552a2d5784",
"parameters": {},
"typeVersion": 1.1
},
{
"id": "df057f13-684a-48e5-8b43-8121ecf4d865",
"name": "Simplify output before giving to Agent",
"type": "n8n-nodes-base.set",
"position": [
3248,
-16
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "9edcaf20-6f14-4c16-a7ad-9b6da44e9bb9",
"name": "html",
"type": "string",
"value": "={{ $json.html }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "7c3e7626-dca0-4915-a051-8b357f7f7366",
"name": "Inform human that there are errors",
"type": "n8n-nodes-base.gmail",
"position": [
4560,
528
],
"webhookId": "4cac94e3-9cd2-46be-b505-2ca619ced59a",
"parameters": {
"sendTo": "[email protected]",
"message": "=Judge wasn't able to review the newsletter of the day. \nNotification time: {{ $now }}.\nAdministrator must review N8N workflow.",
"options": {},
"subject": "=Judge wasn't able to review the newsletter {{ $now }}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "3IbPKCEy8B41xC1R",
"name": "Gmail account 3"
}
},
"typeVersion": 2.1
},
{
"id": "02c6c39e-7991-46cb-9b0e-e0cc460682dc",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
2064,
-352
],
"parameters": {
"color": 4,
"width": 256,
"height": 304,
"content": "## Upon Newsletter Generation\nThis sub-workflow gets triggered by a parent workflow which needs a review of the newsletter by the LLM Judge. \nPrevious node sends the HTML content of the newsletter. "
},
"typeVersion": 1
},
{
"id": "9459af27-5642-4eca-96db-4f6dacad2991",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
4432,
384
],
"parameters": {
"color": 3,
"width": 368,
"height": 352,
"content": "## Workflow error handling\nSomething went wrong with the Agent (could be the model or the parser). Cause should be reviewed by Admin. "
},
"typeVersion": 1
},
{
"id": "a29b6481-d79a-4455-ae88-55c4d74eb131",
"name": "Judge happy ?",
"type": "n8n-nodes-base.if",
"position": [
4192,
-160
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "3733282f-dad1-4751-80c8-722057c9f963",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.output.status }}",
"rightValue": "=PASS"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "9f0ebd7c-0471-4ed1-8095-5a29b182864e",
"name": "Send approval to parent workflow",
"type": "n8n-nodes-base.set",
"position": [
4544,
-288
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "6baf5d1a-3b18-470a-98f5-d7f3844b2c58",
"name": "output.status",
"type": "string",
"value": "={{ $json.output.status }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "6c645c9e-6367-4a15-997f-e0a0f1be30c1",
"name": "Judge 👩⚖️",
"type": "@n8n/n8n-nodes-langchain.agent",
"onError": "continueErrorOutput",
"position": [
3616,
-16
],
"parameters": {
"text": "=# LLM Judge System Prompt - Newsletter Quality Assurance\n\nYou are a Quality Assurance Agent responsible for validating newsletter emails before they are sent to customers. Your role is CRITICAL - you are the last line of defense against sending broken or incomplete emails.\n\n## Your Mission\n\nAnalyze the HTML email that was rendered by Gmail and determine if it's safe to send to customers. If you detect ANY issue, you must BLOCK the send and alert a human.\n\n## What to Check\n\n### 1. Data Completeness\n- All product cards have images (no broken image links or missing `src` attributes)\n- All products have names, prices, and descriptions\n- Original prices and sale prices are both present and formatted correctly\n- The promotion date range is present and makes logical sense (e.g., \"Nov 10 – Nov 16, 2025\")\n- No placeholder text like curly braces, \"undefined\", \"null\", or template variables left unprocessed\n\n### 2. Structural Integrity\n- All 6 product cards are rendered (not fewer, not more)\n- Product grid layout is intact (3 columns × 2 rows)\n- Header with logo and date range is visible\n- Footer with social links and unsubscribe options is present\n- \"View deal\" buttons are present on all cards\n- No broken HTML (unclosed tags, malformed structure)\n\n### 3. Visual Rendering Issues\n- Images are loading correctly (not showing broken image icons)\n- Text is readable (no overlapping, no cut-off content)\n- Colors and styling are applied (not showing unstyled HTML)\n- Buttons and links are styled properly (not plain text)\n- Layout is not collapsed or broken\n\n### 4. Data Logic Validation\n- Sale prices are LOWER than original prices (basic sanity check)\n- Product descriptions are not empty or just whitespace\n- Email subject line contains the correct date range\n- No duplicate products (same productID appearing twice)\n\n## Decision Rules\n\n- **PASS**: Email is perfect, no issues detected → status = \"PASS\", recommendation = \"SEND\"\n- **BLOCK**: Any CRITICAL issue detected → status = \"BLOCK\", recommendation = \"BLOCK_AND_ALERT\"\n- **REVIEW**: Minor issues that might be acceptable → status = \"PASS\", recommendation = \"REVIEW_RECOMMENDED\"\n\n## Critical Issues (Auto-Block)\n\n- Missing product data (no name, price, or image)\n- Broken layout (cards not rendering, structure collapsed)\n- Template variables not replaced (still showing curly braces syntax)\n- Fewer than 6 products loaded\n- Date range is malformed or illogical\n- Any broken image links (HTTP 404)\n\n## Minor Issues (Flag for Review)\n\n- One product description slightly longer than others\n- Minor styling inconsistencies\n- Footer text formatting slightly off\n\n## Example Outputs\n\n### Perfect Email Example\n\n{\n \"status\": \"PASS\",\n \"confidence\": 100,\n \"issues_found\": [],\n \"recommendation\": \"SEND\",\n \"human_alert_message\": null\n}\n\n### Broken Email Example\n\n{\n \"status\": \"BLOCK\",\n \"confidence\": 95,\n \"issues_found\": [\n {\n \"severity\": \"CRITICAL\",\n \"category\": \"data_missing\",\n \"description\": \"Product card #4 has no image - src attribute is empty\",\n \"location\": \"Product card #4 (second row, first column)\"\n },\n {\n \"severity\": \"CRITICAL\",\n \"category\": \"data_missing\",\n \"description\": \"Template variable not replaced.\n \"location\": \"Header date range\"\n }\n ],\n \"recommendation\": \"BLOCK_AND_ALERT\",\n \"human_alert_message\": \"🚨 Newsletter send BLOCKED: Critical data missing (empty image + unprocessed template variable). Manual intervention required before sending to customers.\"\n}\n\n## Remember\n\nYou are protecting the brand reputation. It's better to BLOCK a send and alert a human than to let a broken email reach customers. When in doubt, BLOCK and alert.\n\nBe thorough, be strict, be the guardian of quality.\n\n {{ $json.html }}",
"options": {
"systemMessage": ""
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "4c8418a7-bebc-4b2a-91b6-b08b611f6321",
"name": "GPT5 as the input to review is heavy",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
3536,
304
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5",
"cachedResultName": "gpt-5"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"id": "DIbcbQDS2wPTd9JM",
"name": "OpenAi account 3"
}
},
"typeVersion": 1.3
},
{
"id": "98e7bc74-fcc6-4244-8ce4-83b2fef277a3",
"name": "Expected Format",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
3824,
304
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"status\": {\n \"type\": \"string\",\n \"enum\": [\"PASS\", \"BLOCK\"]\n },\n \"confidence\": {\n \"type\": \"integer\"\n },\n \"issues_found\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"severity\": {\n \"type\": \"string\"\n },\n \"description\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"recommendation\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\"status\", \"confidence\", \"issues_found\", \"recommendation\"]\n}"
},
"typeVersion": 1.3
},
{
"id": "d20d359e-432f-4891-8e81-549e4e5bba4d",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2848,
-352
],
"parameters": {
"color": 4,
"width": 256,
"height": 304,
"content": "## Retrieve Newsletter from Gmail\n\nFetches the sent newsletter back from Gmail to validate the actual rendered output.\n\nThis round-trip ensures we catch any Gmail-specific rendering issues (CSS stripping, image blocking, etc.) before sending to customers. Cost: negligible."
},
"typeVersion": 1
},
{
"id": "84ea1224-6703-4c00-8482-f83afe90fd4b",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
3728,
448
],
"parameters": {
"width": 320,
"height": 208,
"content": "## Judge Output Format\n\nReturns: \n- `status` (PASS/BLOCK)\n- `confidence` (0-100), `issues_found` (array), \n- `recommendation` (action to take)"
},
"typeVersion": 1
},
{
"id": "09f9ea2a-7f33-4b8c-89d8-d81ebc98b226",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
3520,
-352
],
"parameters": {
"color": 4,
"width": 416,
"height": 304,
"content": "## Do Newsletter Quality Assurance\n\nLLM Judge validates the newsletter for completeness and quality:\n- Checks all 6 products have images, prices, and descriptions\n- Verifies layout integrity and date range formatting\n- Detects broken images or unprocessed template variables\n\nReturns: `PASS` to proceed or `BLOCK` with detailed issue report."
},
"typeVersion": 1
},
{
"id": "021816b7-15e8-422b-bb59-cc7e3cebbde1",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
4400,
-560
],
"parameters": {
"color": 4,
"width": 416,
"height": 224,
"content": "## Decision Gate - Send or Alert\n\nBased on the Judge's decision:\n\n✅ **PASS**: Returns success to parent workflow → newsletter gets sent to customers\n\n🚨 **BLOCK**: Sends alert email to admin with issue details → manual review required before sending"
},
"typeVersion": 1
},
{
"id": "042c40a9-17b1-46bf-9392-26c688146073",
"name": "Ask Human to review Newsletter",
"type": "n8n-nodes-base.gmail",
"position": [
4544,
-16
],
"webhookId": "453257a4-7c79-4d34-8dac-91f952dfa131",
"parameters": {
"sendTo": "[email protected]",
"message": "={{ JSON.stringify($json.output, null, 2) }}",
"options": {
"appendAttribution": false
},
"subject": "Newsletter is not approved - view email to see why",
"operation": "sendAndWait",
"responseType": "freeText"
},
"credentials": {
"gmailOAuth2": {
"id": "3IbPKCEy8B41xC1R",
"name": "Gmail account 3"
}
},
"typeVersion": 2.1
},
{
"id": "ceef4768-ba2f-41e3-991b-66d59755ff2d",
"name": "Executed from Newsletter Creation workflow",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
2144,
-16
],
"parameters": {
"inputSource": "passthrough"
},
"typeVersion": 1.1
}
],
"active": false,
"pinData": {
"Judge 👩⚖️": [
{
"json": {
"output": {
"status": "BLOCK",
"confidence": 99,
"issues_found": [
{
"severity": "CRITICAL",
"description": "Header date range unresolved: displays 'Week of undefined' (malformed/missing date)."
},
{
"severity": "CRITICAL",
"description": "All 6 product images use src='undefined' indicating broken image links/placeholders."
},
{
"severity": "CRITICAL",
"description": "Product names, descriptions, and prices are 'undefined' on all 6 product cards (missing data)."
},
{
"severity": "CRITICAL",
"description": "Pricing format invalid: sale/original shown as 'undefined EUR'; cannot verify sale < original."
},
{
"severity": "CRITICAL",
"description": "Unprocessed template variables across product grid (alt text and text content show 'undefined')."
},
{
"severity": "MINOR",
"description": "Email title lacks date range; subject/date alignment cannot be verified."
}
],
"recommendation": "BLOCK_AND_ALERT"
}
}
}
],
"Ask Human to review Newsletter": [
{
"json": {
"data": {
"text": "we failed"
}
}
}
],
"Executed from Newsletter Creation workflow": [
{
"json": {
"html": "<!doctype html>\n<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\">\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta name=\"x-apple-disable-message-reformatting\">\n <meta name=\"format-detection\" content=\"telephone=no, date=no, address=no, email=no\">\n <title>Dog Treats – Weekly Promotions</title>\n <!--[if mso]>\n <style type=\"text/css\">\n table {border-collapse:collapse;border-spacing:0;border:0;margin:0;}\n div, td {padding:0;}\n div {margin:0 !important;}\n </style>\n <noscript>\n <xml>\n <o:OfficeDocumentSettings>\n <o:PixelsPerInch>96</o:PixelsPerInch>\n </o:OfficeDocumentSettings>\n </xml>\n </noscript>\n <![endif]-->\n <style>\n html, body { margin:0 !important; padding:0 !important; background:#fff8f0 !important; height:100% !important; width:100% !important; }\n body { font-family: Arial, Helvetica, sans-serif !important; color:#3b2e2a !important; }\n * { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; }\n table { border-spacing:0 !important; border-collapse:collapse !important; mso-table-lspace:0pt !important; mso-table-rspace:0pt !important; }\n table td { border-collapse: collapse; mso-line-height-rule: exactly; }\n img { border:0; height:auto; line-height:100%; outline:none; text-decoration:none; -ms-interpolation-mode: bicubic; }\n a { color:#c2702d !important; text-decoration:none !important; }\n a img { border:none; }\n h1,h2,h3 { color:#4b2d1f !important; margin:0 !important; }\n p { margin: 0 !important; }\n \n /* Prevent Gmail from changing link colors */\n a[x-apple-data-detectors] { color: inherit !important; text-decoration: none !important; }\n \n @media screen and (max-width:900px){\n .container { width:100% !important; max-width:100% !important; }\n .header, .hero, .grid, .footer { padding-left:16px !important; padding-right:16px !important; }\n .mobile-hide { display:none !important; }\n .card-img { height:auto !important; }\n }\n </style>\n </head>\n <body style=\"margin:0; padding:0; background-color:#fff8f0; font-family:Arial, Helvetica, sans-serif; color:#3b2e2a;\">\n <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"margin:0; padding:0; width:100%; background-color:#fff8f0;\">\n <tr>\n <td align=\"center\" style=\"padding:0;\">\n <table role=\"presentation\" width=\"900\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"width:900px; max-width:900px; margin:24px auto; background-color:#fffaf3; border-radius:12px;\">\n \n <!-- Header -->\n <tr>\n <td style=\"background-color:#f1e0c6; padding:20px 32px; border-bottom:2px solid #e3c18e; color:#4b2d1f;\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n <tr>\n <td style=\"vertical-align:top;\">\n <div style=\"font-size:22px; font-weight:700; color:#4b2d1f; line-height:28px; margin:0;\">\n <img src=\"https://em-content.zobj.net/source/apple/391/bone_1f9b4.png\" alt=\"🦴\" style=\"width:24px; height:24px; display:inline-block; vertical-align:middle; margin-right:4px;\"> Dog Treats\n </div>\n <div style=\"font-size:12px; color:#6e5239; line-height:18px; margin:4px 0 0 0;\">Trusted treats since 2012</div>\n </td>\n <td align=\"right\" style=\"vertical-align:top;\">\n <div style=\"color:#6e5239; font-size:14px; font-weight:bold; line-height:20px;\">Week of undefined</div>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n\n <!-- Hero Section - Cleaned Up -->\n <tr>\n <td style=\"padding:24px 32px; background-color:#fffaf3;\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n <tr>\n <td style=\"padding:0 0 20px 0;\">\n <h1 style=\"margin:0; padding:0; font-size:28px; color:#4b2d1f; line-height:36px; font-weight:700;\">Weekly Promotions</h1>\n </td>\n </tr>\n <tr>\n <td style=\"padding:0;\">\n <p style=\"margin:0; padding:0; font-size:15px; color:#6e5239; line-height:24px;\">All products below are on special promotion this week. Limited stock available.</p>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n\n <!-- Grid 3 columns -->\n <tr>\n <td style=\"padding:16px 32px 24px;\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n <!-- Row 1 -->\n <tr>\n <!-- Item 0 -->\n <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n <tr>\n <td>\n <img src=\"undefined\" alt=\"undefined\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n </td>\n </tr>\n <tr>\n <td style=\"padding:12px;\">\n <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">undefined</div>\n <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">undefined</div>\n <div style=\"margin:8px 0;\">\n <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">undefined EUR</span>\n <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">undefined EUR</span>\n </div>\n <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n </td>\n </tr>\n </table>\n </td>\n \n <!-- Item 1 -->\n <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n <tr>\n <td>\n <img src=\"undefined\" alt=\"undefined\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n </td>\n </tr>\n <tr>\n <td style=\"padding:12px;\">\n <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">undefined</div>\n <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">undefined</div>\n <div style=\"margin:8px 0;\">\n <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">undefined EUR</span>\n <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">undefined EUR</span>\n </div>\n <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n </td>\n </tr>\n </table>\n </td>\n \n <!-- Item 2 -->\n <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n <tr>\n <td>\n <img src=\"undefined\" alt=\"undefined\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n </td>\n </tr>\n <tr>\n <td style=\"padding:12px;\">\n <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">undefined</div>\n <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">undefined</div>\n <div style=\"margin:8px 0;\">\n <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">undefined EUR</span>\n <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">undefined EUR</span>\n </div>\n <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n\n <!-- Row 2 -->\n <tr>\n <!-- Item 3 -->\n <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n <tr>\n <td>\n <img src=\"undefined\" alt=\"undefined\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n </td>\n </tr>\n <tr>\n <td style=\"padding:12px;\">\n <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">undefined</div>\n <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">undefined</div>\n <div style=\"margin:8px 0;\">\n <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">undefined EUR</span>\n <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">undefined EUR</span>\n </div>\n <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n </td>\n </tr>\n </table>\n </td>\n \n <!-- Item 4 -->\n <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n <tr>\n <td>\n <img src=\"undefined\" alt=\"undefined\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n </td>\n </tr>\n <tr>\n <td style=\"padding:12px;\">\n <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">undefined</div>\n <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">undefined</div>\n <div style=\"margin:8px 0;\">\n <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">undefined EUR</span>\n <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">undefined EUR</span>\n </div>\n <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n </td>\n </tr>\n </table>\n </td>\n \n <!-- Item 5 -->\n <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n <tr>\n <td>\n <img src=\"undefined\" alt=\"undefined\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n </td>\n </tr>\n <tr>\n <td style=\"padding:12px;\">\n <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">undefined</div>\n <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">undefined</div>\n <div style=\"margin:8px 0;\">\n <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">undefined EUR</span>\n <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">undefined EUR</span>\n </div>\n <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n\n <!-- Footer -->\n <tr>\n <td style=\"padding:24px 32px; background-color:#fff3e0; font-size:12px; color:#7a5b42; text-align:center; border-top:1px solid #f0e0c7;\">\n <div style=\"margin:0 0 16px 0; line-height:18px;\">\n Dog Treats - 123 Bone Street, Paris 75000<br>\n <a href=\"mailto:[email protected]\" style=\"color:#7a5b42; text-decoration:underline;\">[email protected]</a>\n </div>\n \n <!-- Social Icons with PNG images -->\n <table role=\"presentation\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"margin:16px auto;\">\n <tr>\n <td style=\"padding:0 8px;\">\n <a href=\"https://instagram.com/dogtreats\" title=\"Instagram\" style=\"display:inline-block;\">\n <img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Instagram_logo_2016.svg/132px-Instagram_logo_2016.svg.png\" alt=\"Instagram\" style=\"width:40px; height:40px; display:block; border:0;\">\n </a>\n </td>\n <td style=\"padding:0 8px;\">\n <a href=\"https://facebook.com/dogtreats\" title=\"Facebook\" style=\"display:inline-block;\">\n <img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/2023_Facebook_icon.svg/100px-2023_Facebook_icon.svg.png\" alt=\"Facebook\" style=\"width:40px; height:40px; display:block; border:0;\">\n </a>\n </td>\n <td style=\"padding:0 8px;\">\n <a href=\"https://tiktok.com/@dogtreats\" title=\"TikTok\" style=\"display:inline-block;\">\n <img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Ionicons_logo-tiktok.svg/512px-Ionicons_logo-tiktok.svg.png\" alt=\"TikTok\" style=\"width:40px; height:40px; display:block; border:0;\">\n </a>\n </td>\n </tr>\n </table>\n \n <p style=\"margin:16px 0 0 0; line-height:18px;\"><a href=\"https://tiktok.com/@dogtreats\" style=\"color:#7a5b42; text-decoration:underline;\">Follow us on TikTok</a></p>\n \n <div style=\"margin:12px 0 0 0; font-size:11px; line-height:16px;\">\n <p style=\"margin:0; line-height:16px;\">You're receiving this because you subscribed to Weekly Promotions.<br>\n <a href=\"https://dogtreats.example/preferences\" style=\"color:#6e5b42; text-decoration:underline;\">Manage preferences</a> - <a href=\"https://dogtreats.example/unsubscribe\" style=\"color:#6e5b42; text-decoration:underline;\">Unsubscribe</a></p>\n </div>\n </td>\n </tr>\n\n </table>\n </td>\n </tr>\n </table>\n </body>\n</html>"
}
}
]
},
"settings": {
"executionOrder": "v1"
},
"versionId": "30e85b9e-5019-4aae-8308-076f5e02ba5e",
"connections": {
"Judge happy ?": {
"main": [
[
{
"node": "Send approval to parent workflow",
"type": "main",
"index": 0
}
],
[
{
"node": "Ask Human to review Newsletter",
"type": "main",
"index": 0
}
]
]
},
"Expected Format": {
"ai_outputParser": [
[
{
"node": "Judge 👩⚖️",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Get the newsletter": {
"main": [
[
{
"node": "Simplify output before giving to Agent",
"type": "main",
"index": 0
}
]
]
},
"Judge 👩⚖️": {
"main": [
[
{
"node": "Judge happy ?",
"type": "main",
"index": 0
}
],
[
{
"node": "Inform human that there are errors",
"type": "main",
"index": 0
}
]
]
},
"Send newsletter to LLM Judge": {
"main": [
[
{
"node": "Give the email some time to arrive",
"type": "main",
"index": 0
}
]
]
},
"Give the email some time to arrive": {
"main": [
[
{
"node": "Get the newsletter",
"type": "main",
"index": 0
}
]
]
},
"GPT5 as the input to review is heavy": {
"ai_languageModel": [
[
{
"node": "Judge 👩⚖️",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Simplify output before giving to Agent": {
"main": [
[
{
"node": "Judge 👩⚖️",
"type": "main",
"index": 0
}
]
]
},
"Executed from Newsletter Creation workflow": {
"main": [
[
{
"node": "Send newsletter to LLM Judge",
"type": "main",
"index": 0
}
]
]
}
}
}