{
  "id": "YeRc5dHhphL5l3v0",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true
  },
  "name": "Check Japanese ad copy for regulatory risk with Gemini, Sheets and Slack",
  "tags": [],
  "nodes": [
    {
      "id": "36c80240-5f58-42e7-8430-c3133b548be2",
      "name": "Schedule Daily Check",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        208,
        96
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "9b62cab5-fc81-4fee-8b85-b9519b938ad9",
      "name": "Get Unchecked Copy",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        432,
        96
      ],
      "parameters": {
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "Ad Copy"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "Select your spreadsheet"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "30240466-404c-4ca0-afa1-0c138750d524",
      "name": "Set Review Policy",
      "type": "n8n-nodes-base.set",
      "position": [
        640,
        96
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cat",
              "name": "productCategory",
              "type": "string",
              "value": "Health supplement"
            },
            {
              "id": "laws",
              "name": "targetLaws",
              "type": "string",
              "value": "Pharmaceutical and Medical Device Act, Act against Unjustifiable Premiums and Misleading Representations"
            },
            {
              "id": "note",
              "name": "extraRules",
              "type": "string",
              "value": "No guaranteed results, no medical efficacy claims, no unsupported No.1 claims."
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "84280e10-8254-45a0-8445-c4aa1e436959",
      "name": "Check Copy with Gemini",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "onError": "continueErrorOutput",
      "position": [
        912,
        96
      ],
      "parameters": {
        "text": "=You are a Japanese advertising compliance reviewer. Review the marketing copy below against {{ $json.targetLaws }} for a product in the category \"{{ $json.productCategory }}\". Extra rules: {{ $json.extraRules }}\n\nReturn risk_level as high when the copy clearly violates the law, medium when it is risky or ambiguous, low when it is safe. List every problematic phrase with the law it breaches and why, then provide a compliant rewrite in Japanese.\n\nMarketing copy:\n{{ $json.Copy }}",
        "batching": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.9
    },
    {
      "id": "87fbd36d-bfcd-4bb9-8243-10cab5dec36e",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        896,
        288
      ],
      "parameters": {
        "options": {
          "temperature": 0.1
        },
        "modelName": "models/gemini-3.1-flash-lite"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "14bc4cb5-0095-41e1-88c0-52bfac2246e5",
      "name": "Risk Result Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1088,
        288
      ],
      "parameters": {
        "jsonSchemaExample": "{\"risk_level\":\"high\",\"violations\":[{\"phrase\":\"\u5fc5\u305a\u75e9\u305b\u307e\u3059\",\"law\":\"Pharmaceutical and Medical Device Act\",\"reason\":\"Guaranteed medical effect is not allowed\"}],\"safe_rewrite\":\"\u6bce\u65e5\u306e\u98df\u751f\u6d3b\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u307e\u3059\",\"summary\":\"Claims a guaranteed slimming effect\"}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "8823659d-f0e7-469d-bae5-7a2b26a9b003",
      "name": "Parse Risk Result",
      "type": "n8n-nodes-base.code",
      "position": [
        1328,
        80
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const src = $json.output || $json;\nconst row = $('Set Review Policy').item.json;\nconst v = Array.isArray(src.violations) ? src.violations : [];\nconst violations = v.map(function (x) { return (x.phrase || '') + ' [' + (x.law || '') + '] ' + (x.reason || ''); }).join(' | ');\nreturn {\n  copyId: row['Copy ID'] || row.copyId || '',\n  copy: row.Copy || row.copy || '',\n  riskLevel: String(src.risk_level || 'medium').toLowerCase(),\n  violations: violations,\n  violationCount: v.length,\n  safeRewrite: src.safe_rewrite || '',\n  summary: src.summary || ''\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "be15acb1-50b0-4e47-9fb4-8d611874f42a",
      "name": "Update Copy Row",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1696,
        80
      ],
      "parameters": {
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "Ad Copy"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "Select your spreadsheet"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "883a0d76-2586-428a-beef-d28a903b9c38",
      "name": "Route by Risk Level",
      "type": "n8n-nodes-base.switch",
      "position": [
        2048,
        48
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $(\"Parse Risk Result\").item.json.riskLevel }}",
                    "rightValue": "high"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $(\"Parse Risk Result\").item.json.riskLevel }}",
                    "rightValue": "medium"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $(\"Parse Risk Result\").item.json.riskLevel }}",
                    "rightValue": "low"
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "Other"
        }
      },
      "typeVersion": 3.2
    },
    {
      "id": "dafe78f4-c040-4594-b249-c69fdb06a166",
      "name": "Block and Alert Legal",
      "type": "n8n-nodes-base.slack",
      "position": [
        2272,
        32
      ],
      "parameters": {
        "text": "=*:rotating_light: High-risk ad copy blocked*\n*Copy ID:* {{ $(\"Parse Risk Result\").item.json.copyId }}\n*Issues:* {{ $(\"Parse Risk Result\").item.json.violations }}\n*Suggested rewrite:* {{ $(\"Parse Risk Result\").item.json.safeRewrite }}\nDo not publish until legal signs off.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "#legal-review"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "9d65b92f-ed9b-496b-9f3a-cee1f9c5144c",
      "name": "Draft Revision Request",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2512,
        32
      ],
      "parameters": {
        "message": "={{ \"Hi,\\n\\nThe following ad copy cannot be published as written:\\n\\n\" + $(\"Parse Risk Result\").item.json.copy + \"\\n\\nIssues found:\\n\" + $(\"Parse Risk Result\").item.json.violations + \"\\n\\nSuggested compliant rewrite:\\n\" + $(\"Parse Risk Result\").item.json.safeRewrite + \"\\n\\nPlease revise and resubmit.\" }}",
        "options": {},
        "subject": "={{ \"Revision required - ad copy \" + $(\"Parse Risk Result\").item.json.copyId }}",
        "resource": "draft"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "74a5cc4f-000d-4681-96d9-4a660adfc16a",
      "name": "Request Marketing Review",
      "type": "n8n-nodes-base.slack",
      "position": [
        2272,
        208
      ],
      "parameters": {
        "text": "=*:eyes: Ad copy needs a second look*\n*Copy ID:* {{ $(\"Parse Risk Result\").item.json.copyId }}\n*Summary:* {{ $(\"Parse Risk Result\").item.json.summary }}\n*Suggested rewrite:* {{ $(\"Parse Risk Result\").item.json.safeRewrite }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "#marketing"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "4bed0302-0646-4561-b484-0368a19af57b",
      "name": "Notify Ready to Publish",
      "type": "n8n-nodes-base.slack",
      "position": [
        2272,
        400
      ],
      "parameters": {
        "text": "=*:white_check_mark: Ad copy passed the compliance check*\n*Copy ID:* {{ $(\"Parse Risk Result\").item.json.copyId }}\nReady to publish.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "#marketing"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "599e0b62-6a00-4934-bd49-dfa512af0a5f",
      "name": "Flag Unclassified Copy",
      "type": "n8n-nodes-base.slack",
      "position": [
        2272,
        576
      ],
      "parameters": {
        "text": "=*:mag: Compliance result was inconclusive*\n*Copy ID:* {{ $(\"Parse Risk Result\").item.json.copyId }}\nPlease review manually.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "#marketing"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "53aac623-b7fe-4829-91ae-bacab7ab3563",
      "name": "Report Check Failure",
      "type": "n8n-nodes-base.slack",
      "position": [
        1328,
        288
      ],
      "parameters": {
        "text": "=*:x: Compliance check failed for copy {{ $(\"Set Review Policy\").item.json[\"Copy ID\"] }}*\nPlease review this copy manually before publishing.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "#marketing"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "8701b170-2f36-4c64-898e-c9c56fbf174b",
      "name": "Overview Sticky",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -464,
        -128
      ],
      "parameters": {
        "width": 568,
        "height": 660,
        "content": "## Check Japanese ad copy for regulatory risk with Gemini, Sheets and Slack\n\n### How it works\nJapanese marketing copy has to comply with the Pharmaceutical and Medical Device Act and the Act against Unjustifiable Premiums and Misleading Representations - a single \"guaranteed results\" phrase can trigger a fine. Each day this template reads unchecked copy from Google Sheets and sends it to a Basic LLM Chain with Google Gemini, which returns a risk level, every problematic phrase with the law it breaches, and a compliant rewrite. The row is updated and marked Checked so nothing is reviewed twice, then a Switch routes by risk: high-risk copy is blocked with a legal alert plus a revision-request email draft, medium goes to marketing review, low is cleared for publishing, and anything unclear is flagged.\n\n### Setup\n1. Connect Google Sheets, Google Gemini (PaLM) API, Gmail and Slack.\n2. Create a sheet with Copy ID, Copy and an empty Status column.\n3. In **Set Review Policy**, set the product category and the rules to enforce.\n\n### Customization tips\nAdd more laws, change the risk bands, or auto-send revision requests."
      },
      "typeVersion": 1
    },
    {
      "id": "f253f70d-05d4-46af-b96f-2f1f1abf916b",
      "name": "S1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 900,
        "content": "## 1. Fetch unchecked copy & configure\nRead only rows without a Status, then set the product category and the rules to enforce."
      },
      "typeVersion": 1
    },
    {
      "id": "05409f16-8fcc-4ba7-aab8-f298fb8f2d58",
      "name": "S2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        816,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 712,
        "height": 900,
        "content": "## 2. AI compliance check (Basic LLM Chain)\nGemini returns a risk level, the offending phrases with the law they breach, and a compliant rewrite. Failures are reported to Slack."
      },
      "typeVersion": 1
    },
    {
      "id": "215d361a-6918-4689-9834-270a8ad8c83b",
      "name": "S3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1552,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 396,
        "height": 900,
        "content": "## 3. Persist & de-duplicate\nWrite the result back to the row (match on Copy ID) and set Status = Checked so copy is never reviewed twice."
      },
      "typeVersion": 1
    },
    {
      "id": "94aaab81-1cfc-487f-b8a8-e741dcc02576",
      "name": "S4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1968,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 740,
        "height": 900,
        "content": "## 4. Route by risk & act\nHigh blocks with a legal alert and a revision-request draft. Medium goes to marketing review. Low is cleared to publish. Anything else is flagged."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "ab3f4915-e117-4ca1-8570-4e3c627f494c",
  "nodeGroups": [],
  "connections": {
    "Update Copy Row": {
      "main": [
        [
          {
            "node": "Route by Risk Level",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Risk Result": {
      "main": [
        [
          {
            "node": "Update Copy Row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Review Policy": {
      "main": [
        [
          {
            "node": "Check Copy with Gemini",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Unchecked Copy": {
      "main": [
        [
          {
            "node": "Set Review Policy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Risk Result Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Check Copy with Gemini",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Route by Risk Level": {
      "main": [
        [
          {
            "node": "Block and Alert Legal",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Request Marketing Review",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify Ready to Publish",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Flag Unclassified Copy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Daily Check": {
      "main": [
        [
          {
            "node": "Get Unchecked Copy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Block and Alert Legal": {
      "main": [
        [
          {
            "node": "Draft Revision Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Copy with Gemini": {
      "main": [
        [
          {
            "node": "Parse Risk Result",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Report Check Failure",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Check Copy with Gemini",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  }
}