AutomationFlowsWeb Scraping › Automated FANZA Review Generator

Automated FANZA Review Generator

Original n8n title: Fanza Review Auto-generator (phase 1)

FANZA Review Auto-Generator (Phase 1). Uses httpRequest, emailSend. Scheduled trigger; 14 nodes.

Cron / scheduled trigger★★★★☆ complexity14 nodesHTTP RequestEmail Send
Web Scraping Trigger: Cron / scheduled Nodes: 14 Complexity: ★★★★☆ Added:

This workflow follows the Emailsend → HTTP Request recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "FANZA Review Auto-Generator (Phase 1)",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 3 * * 0"
            }
          ]
        }
      },
      "id": "schedule-trigger",
      "name": "Schedule Trigger (Weekly Sun 03:00 JST)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        100,
        300
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "c1",
              "name": "dmmApiId",
              "value": "={{ $env.DMM_API_ID }}",
              "type": "string"
            },
            {
              "id": "c2",
              "name": "affiliateId",
              "value": "ikuoji-990",
              "type": "string"
            },
            {
              "id": "c3",
              "name": "hits",
              "value": 10,
              "type": "number"
            },
            {
              "id": "c4",
              "name": "wpBaseUrl",
              "value": "https://princess-kira-adult.com",
              "type": "string"
            },
            {
              "id": "c5",
              "name": "anthropicModel",
              "value": "claude-haiku-4-5",
              "type": "string"
            },
            {
              "id": "c7",
              "name": "notifyEmail",
              "value": "manatsusuki@gmail.com",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "config",
      "name": "Config",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        320,
        300
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://api.dmm.com/affiliate/v3/ItemList",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "api_id",
              "value": "={{ $json.dmmApiId }}"
            },
            {
              "name": "affiliate_id",
              "value": "={{ $json.affiliateId }}"
            },
            {
              "name": "site",
              "value": "FANZA"
            },
            {
              "name": "service",
              "value": "digital"
            },
            {
              "name": "floor",
              "value": "videoa"
            },
            {
              "name": "hits",
              "value": "={{ $json.hits }}"
            },
            {
              "name": "sort",
              "value": "date"
            },
            {
              "name": "output",
              "value": "json"
            }
          ]
        },
        "options": {
          "timeout": 30000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      },
      "id": "dmm-item-list",
      "name": "DMM API ItemList",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        540,
        300
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000
    },
    {
      "parameters": {
        "jsCode": "// Extract items from DMM API response + build affiliate URL per item\nconst resp = $input.first().json;\nconst items = (resp.result && resp.result.items) || [];\nconst join = (arr, f) => (arr || []).map(x => x[f]).filter(Boolean).join(', ');\nconst out = [];\nfor (const it of items) {\n  const info = it.iteminfo || {};\n  const productUrl = it.URL || '';\n  const affiliateUrl =\n    'https://al.dmm.co.jp/?lurl=' + encodeURIComponent(productUrl) +\n    '&af_id=ikuoji-002-001&ch=link_tool&ch_id=text';\n  out.push({ json: {\n    product_id: it.content_id || '',\n    product_title: it.title || '',\n    actress: join(info.actress, 'name'),\n    genre: join(info.genre, 'name'),\n    release_date: it.date || '',\n    duration: it.volume || '',\n    label: ((info.label || [])[0] || {}).name || '',\n    series: ((info.series || [])[0] || {}).name || '',\n    description: it.comment || it.title || '',\n    thumbnail_url: (it.imageURL || {}).large || (it.imageURL || {}).list || '',\n    product_url: productUrl,\n    affiliate_url: affiliateUrl\n  }});\n}\nif (out.length === 0) {\n  return [{ json: { _empty: true, message: 'No items returned from DMM API' } }];\n}\nreturn out;"
      },
      "id": "extract-items",
      "name": "Extract Items",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        760,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Build Claude API request body with prompt-caching on system prompt.\n// System prompt is kept verbatim here so n8n needs no external file read.\nconst SYSTEM_PROMPT = [\n  '\u3042\u306a\u305f\u306f\u30a2\u30c0\u30eb\u30c8\u52d5\u753b\u30ec\u30d3\u30e5\u30fc\u30d6\u30ed\u30b0\u300cprincess-kira-adult.com\u300d\u306e\u30e9\u30a4\u30bf\u30fc\u3067\u3059\u3002DMM Web Service API \u304b\u3089\u6e21\u3055\u308c\u308b\u4f5c\u54c1\u60c5\u5831\u3092\u3082\u3068\u306b\u3001SEO \u3068\u30b3\u30f3\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u4e21\u7acb\u3059\u308b\u65e5\u672c\u8a9e\u30ec\u30d3\u30e5\u30fc\u8a18\u4e8b\u30921\u672c\u751f\u6210\u3057\u307e\u3059\u3002',\n  '',\n  '## \u51fa\u529b\u5f62\u5f0f',\n  'JSON \u306e\u307f\u8fd4\u5374\u3002\u524d\u5f8c\u306b\u5730\u306e\u6587\u3084 ``` \u3092\u4ed8\u3051\u306a\u3044\u3002',\n  '{',\n  '  \"title\": \"h1 \u30bf\u30a4\u30c8\u30eb\uff0860\u6587\u5b57\u4ee5\u5185\u3001\u5973\u512a\u540d\u3068\u4f5c\u54c1\u30bf\u30a4\u30c8\u30eb\u306e\u8981\u7d20\u3092\u542b\u3080\uff09\",',\n  '  \"excerpt\": \"\u30ea\u30fc\u30c9\u6587\u306e\u5192\u982d150\u6587\u5b57\",',\n  '  \"content_html\": \"<p>\u301c</p>... HTML \u672c\u6587\uff082000\u301c3000\u6587\u5b57\uff09\",',\n  '  \"categories\": [\"FANZA\u30ec\u30d3\u30e5\u30fc\", \"\u5973\u512a\u540d1\"],',\n  '  \"tags\": [\"\u30b8\u30e3\u30f3\u30eb1\"],',\n  '  \"compliance_check\": {\"has_pr\": true, \"has_18_plus\": true, \"no_forbidden_words\": true, \"affiliate_link_count\": 1, \"char_count_in_range\": true}',\n  '}',\n  '',\n  '## \u8a18\u4e8b\u69cb\u6210\uff08content_html\uff09',\n  '1. \u30ea\u30fc\u30c9\u6587\uff08200\u5b57\u7a0b\u5ea6\uff09',\n  '2. <h2>\u4f5c\u54c1\u60c5\u5831</h2> \u3068 HTML table\uff08\u5973\u512a/\u30b8\u30e3\u30f3\u30eb/\u767a\u58f2\u65e5/\u53ce\u9332\u6642\u9593/\u30ec\u30fc\u30d9\u30eb/\u30b7\u30ea\u30fc\u30ba\uff09',\n  '3. <img src=\"{{THUMBNAIL_URL}}\" alt=\"{{PRODUCT_TITLE}}\">\uff08table\u76f4\u5f8c\u30011\u679a\u306e\u307f\uff09',\n  '4. <h2>\u898b\u3069\u3053\u308d</h2> 3\u9805\u76ee',\n  '5. <h2>\u5973\u512a\u7d39\u4ecb</h2>\uff08API\u3067\u5f97\u3089\u308c\u308b\u7bc4\u56f2\u306e\u307f\u3001\u79c1\u751f\u6d3b\u306b\u8e0f\u307f\u8fbc\u307e\u306a\u3044\uff09',\n  '6. <h2>\u8996\u8074\u8005\u306e\u58f0\uff08\u4e88\u60f3\uff09</h2> 3\u8996\u70b9\u3001\u300c\u301c\u3068\u3044\u3046\u611f\u60f3\u3082\u51fa\u305d\u3046\u3067\u3059\u300d\u5f62\u5f0f',\n  '7. <h2>\u4f5c\u54c1\u3092\u8996\u8074\u3059\u308b</h2> \u2192 <p><a href=\"{{AFFILIATE_URL}}\" class=\"btn-affiliate\" target=\"_blank\" rel=\"noopener noreferrer\">FANZA\u3067\u8996\u8074\u3059\u308b</a></p>',\n  '8. \u672b\u5c3e\u514d\u8cac: <hr><p class=\"disclosure\">#PR / \u672c\u8a18\u4e8b\u306f\u30d7\u30ed\u30e2\u30fc\u30b7\u30e7\u30f3\u3092\u542b\u307f\u307e\u3059\u300218\u6b73\u672a\u6e80\u306e\u65b9\u306f\u8996\u8074\u3067\u304d\u307e\u305b\u3093\u3002\u4f5c\u54c1\u60c5\u5831\u306f\u63b2\u8f09\u6642\u70b9\u306e\u3082\u306e\u3067\u3059\u3002\u500b\u4eba\u306e\u611f\u60f3\u3092\u542b\u307f\u307e\u3059\u3002</p>',\n  '',\n  '## \u5fc5\u9808\u8981\u7d20',\n  '- \u672c\u65872000\u301c3000\u6587\u5b57\uff08HTML\u30bf\u30b0\u9664\u5916\u3067\u8a08\u7b97\uff09',\n  '- \u672b\u5c3edisclosure\u306b #PR \u3068 18\u6b73\u672a\u6e80 \u3092\u5fc5\u305a\u542b\u3081\u308b',\n  '- \u30a2\u30d5\u30a3\u30ea\u30a8\u30a4\u30c8\u30ea\u30f3\u30af\u306f CTA \u306e1\u7b87\u6240\u306e\u307f\u3001rel=\"noopener noreferrer\"',\n  '- \u30b5\u30e0\u30cd\u30a4\u30eb img \u306f1\u679a\u3001alt \u306b\u30bf\u30a4\u30c8\u30eb',\n  '',\n  '## \u7981\u6b62\u8868\u73fe',\n  '- \u65ad\u5b9a: \u7d76\u5bfe/\u5fc5\u305a/100%/\u9593\u9055\u3044\u306a\u304f/\u78ba\u5b9f\u306b',\n  '- \u8a87\u5927: \u6700\u9ad8\u5091\u4f5c/\u53f2\u4e0a\u6700\u9ad8/\u795e\u4f5c/\u81f3\u9ad8/\u552f\u4e00\u7121\u4e8c',\n  '- \u9732\u9aa8\u306a\u6027\u884c\u70ba\u306e\u5177\u4f53\u63cf\u5199\u3001\u672a\u6210\u5e74\u3078\u306e\u8a00\u53ca\u3001\u5973\u512a\u4ee5\u5916\u306e\u5b9f\u5728\u500b\u4eba\u540d',\n  '',\n  '## \u30c8\u30fc\u30f3',\n  '- \u5ba2\u89b3\u7684\u3067\u843d\u3061\u7740\u3044\u305f\u8a9e\u308a\u53e3',\n  '- \u300c\u301c\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u300d\u300c\u301c\u3068\u3044\u3046\u5370\u8c61\u300d\u300c\u301c\u3068\u611f\u3058\u308b\u65b9\u3082\u3044\u305d\u3046\u3067\u3059\u300d'\n].join('\\n');\n\nconst model = $('Config').item.json.anthropicModel;\nconst results = [];\nfor (const it of $input.all()) {\n  const d = it.json;\n  const USER_PROMPT = [\n    '## \u4f5c\u54c1\u60c5\u5831',\n    '- \u5546\u54c1ID: ' + d.product_id,\n    '- \u30bf\u30a4\u30c8\u30eb: ' + d.product_title,\n    '- \u5973\u512a: ' + d.actress,\n    '- \u30b8\u30e3\u30f3\u30eb: ' + d.genre,\n    '- \u767a\u58f2\u65e5: ' + d.release_date,\n    '- \u53ce\u9332\u6642\u9593: ' + d.duration,\n    '- \u30ec\u30fc\u30d9\u30eb: ' + d.label,\n    '- \u30b7\u30ea\u30fc\u30ba: ' + d.series,\n    '- \u5546\u54c1\u8aac\u660e: ' + d.description,\n    '- \u30b5\u30e0\u30cd\u30a4\u30eb: ' + d.thumbnail_url,\n    '- \u30a2\u30d5\u30a3\u30ea\u30a8\u30a4\u30c8URL: ' + d.affiliate_url,\n    '',\n    '\u4e0a\u8a18\u3092\u3082\u3068\u306b\u3001\u30b7\u30b9\u30c6\u30e0\u6307\u793a\u306b\u5f93\u3044 JSON \u3092\u8fd4\u3057\u3066\u304f\u3060\u3055\u3044\u3002'\n  ].join('\\n');\n  const anthropicBody = {\n    model: model,\n    max_tokens: 4500,\n    temperature: 0.7,\n    system: [ { type: 'text', text: SYSTEM_PROMPT, cache_control: { type: 'ephemeral' } } ],\n    messages: [ { role: 'user', content: USER_PROMPT } ]\n  };\n  results.push({ json: { ...d, anthropicBody } });\n}\nreturn results;"
      },
      "id": "build-prompt",
      "name": "Build Claude Prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        980,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $env.ANTHROPIC_API_KEY }}"
            },
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "anthropic-beta",
              "value": "prompt-caching-2024-07-31"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json.anthropicBody) }}",
        "options": {
          "timeout": 120000,
          "response": {
            "response": {
              "responseFormat": "json",
              "neverError": true
            }
          },
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 25000
            }
          }
        }
      },
      "id": "claude-call",
      "name": "Claude Haiku API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1200,
        300
      ],
      "retryOnFail": true,
      "maxTries": 2,
      "waitBetweenTries": 10000
    },
    {
      "parameters": {
        "jsCode": "function validateCompliance(gen) {\n  const html = (gen && gen.content_html) || '';\n  const textOnly = html.replace(/<[^>]+>/g, '');\n  const forbidden = /(\u7d76\u5bfe|\u5fc5\u305a|100%|\u9593\u9055\u3044\u306a\u304f|\u6700\u9ad8\u5091\u4f5c|\u795e\u4f5c|\u81f3\u9ad8)/;\n  const affiliateMatches = html.match(/al\\.dmm\\.co\\.jp/g) || [];\n  return {\n    has_pr: /#PR/.test(html),\n    has_18_plus: /18\u6b73\u672a\u6e80|18\u7981/.test(html),\n    no_forbidden_words: !forbidden.test(textOnly),\n    affiliate_link_count: affiliateMatches.length,\n    char_count_in_range: textOnly.length >= 1200 && textOnly.length <= 4000,\n    char_count: textOnly.length\n  };\n}\n\nfunction extractJson(text) {\n  let s = text.trim();\n  const fence = s.match(/^```(?:json)?\\s*([\\s\\S]*?)\\s*```\\s*$/);\n  if (fence) s = fence[1].trim();\n  const first = s.indexOf('{');\n  const last = s.lastIndexOf('}');\n  if (first >= 0 && last > first) s = s.slice(first, last+1);\n  return JSON.parse(s);\n}\n\nconst out = [];\nfor (const item of $input.all()) {\n  const ctx = item.json;\n  const resp = ctx;\n  let generated = null;\n  let parseError = null;\n  let rawText = '';\n  try {\n    if (resp.error) {\n      parseError = \"api:\" + (resp.error.type || \"unknown\") + \":\" + (resp.error.message || \"\").slice(0,120);\n    } else {\n      rawText = ((resp.content || [])[0] || {}).text || \"\";\n      generated = extractJson(rawText);\n    }\n  } catch (e) {\n    parseError = e.message;\n  }\n  const compliance = generated ? validateCompliance(generated) : {\n    has_pr: false, has_18_plus: false, no_forbidden_words: false,\n    affiliate_link_count: 0, char_count_in_range: false, char_count: 0\n  };\n  const pass = compliance.has_pr && compliance.has_18_plus && compliance.no_forbidden_words\n    && compliance.affiliate_link_count === 1 && compliance.char_count_in_range;\n  out.push({ json: {\n    product_id: ctx.product_id,\n    product_title: ctx.product_title,\n    affiliate_url: ctx.affiliate_url,\n    generated,\n    parseError,\n    rawTextPreview: rawText.slice(0, 120),\n    compliance,\n    pass\n  }});\n}\nreturn out;"
      },
      "id": "validate",
      "name": "Parse & Validate",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1420,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "i1",
              "leftValue": "={{ $json.pass }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "if-pass",
      "name": "IF compliance pass",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1640,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $('Config').item.json.wpBaseUrl }}/wp-json/wp/v2/posts",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({\n  title: $json.generated.title,\n  content: $json.generated.content_html,\n  excerpt: $json.generated.excerpt,\n  status: 'draft'\n}) }}",
        "options": {
          "timeout": 30000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      },
      "id": "wp-post",
      "name": "WordPress Draft Post",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1860,
        220
      ],
      "retryOnFail": true,
      "maxTries": 2,
      "waitBetweenTries": 5000,
      "credentials": {
        "httpBasicAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const out = [];\nfor (const it of $input.all()) {\n  const r = it.json;\n  out.push({ json: {\n    product_id: r.product_id,\n    product_title: r.product_title,\n    wp_post_id: (r.id !== undefined) ? r.id : null,\n    wp_link: r.link || null,\n    status: 'draft_created'\n  }});\n}\nreturn out;"
      },
      "id": "success-record",
      "name": "Success Record",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2080,
        220
      ]
    },
    {
      "parameters": {
        "jsCode": "const out = [];\nfor (const it of $input.all()) {\n  const r = it.json;\n  const c = r.compliance || {};\n  const reasons = [];\n  if (r.parseError) reasons.push('parse:' + r.parseError);\n  if (c.has_pr === false) reasons.push('no #PR');\n  if (c.has_18_plus === false) reasons.push('no 18+');\n  if (c.no_forbidden_words === false) reasons.push('forbidden_word');\n  if (c.affiliate_link_count !== undefined && c.affiliate_link_count !== 1) reasons.push('aff_count=' + c.affiliate_link_count);\n  if (c.char_count_in_range === false) reasons.push('char_range_ng');\n  out.push({ json: {\n    product_id: r.product_id || '',\n    product_title: r.product_title || '',\n    wp_post_id: null,\n    wp_link: null,\n    status: 'compliance_failed',\n    failure_reason: reasons.join(' | ') || 'unknown',\n    compliance: c\n  }});\n}\nreturn out;"
      },
      "id": "failure-record",
      "name": "Failure Record",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1860,
        380
      ]
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {
          "mergeLists": false
        }
      },
      "id": "aggregate-success",
      "name": "Aggregate Success",
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        2300,
        220
      ]
    },
    {
      "parameters": {
        "jsCode": "const items = ($input.first().json.data) || [];\nconst success = items.filter(i => i.status === 'draft_created');\nconst failed = items.filter(i => i.status !== 'draft_created');\nconst esc = s => String(s||'').replace(/</g,'&lt;');\nconst rowsS = success.map((it, i) => `<tr><td>${i+1}</td><td>${esc(it.product_title)}</td><td>${esc(it.product_id)}</td><td><a href=\"${it.wp_link||'#'}\">\u4e0b\u66f8\u304d\u3092\u958b\u304f</a></td></tr>`).join('');\nconst rowsF = failed.map((it, i) => `<tr><td>${i+1}</td><td>${esc(it.product_title)}</td><td>${esc(it.product_id)}</td><td>${esc(it.failure_reason)}</td></tr>`).join('');\nconst html = `\n<h2>FANZA\u30ec\u30d3\u30e5\u30fc\u81ea\u52d5\u5316 \u5b9f\u884c\u30b5\u30de\u30ea</h2>\n<p>\u5b9f\u884c: ${new Date().toLocaleString('ja-JP')}</p>\n<p>\u4e0b\u66f8\u304d\u6295\u5165: ${success.length}\u4ef6 / \u4e0d\u63a1\u7528: ${failed.length}\u4ef6</p>\n<h3>\u4e0b\u66f8\u304d\u6295\u5165</h3>\n<table border=\"1\" cellpadding=\"6\" style=\"border-collapse:collapse;font-family:sans-serif\">\n  <thead><tr style=\"background:#f0f0f0\"><th>#</th><th>\u4f5c\u54c1\u30bf\u30a4\u30c8\u30eb</th><th>\u5546\u54c1ID</th><th>WP</th></tr></thead>\n  <tbody>${rowsS||'<tr><td colspan=4>\u306a\u3057</td></tr>'}</tbody>\n</table>\n${failed.length ? `<h3>\u30b3\u30f3\u30d7\u30e9\u30a4\u30a2\u30f3\u30b9\u4e0d\u901a\u904e\uff08\u4e0d\u63a1\u7528\uff09</h3>\n<table border=\"1\" cellpadding=\"6\" style=\"border-collapse:collapse;font-family:sans-serif\">\n  <thead><tr style=\"background:#fee\"><th>#</th><th>\u4f5c\u54c1\u30bf\u30a4\u30c8\u30eb</th><th>\u5546\u54c1ID</th><th>\u4e0d\u63a1\u7528\u7406\u7531</th></tr></thead>\n  <tbody>${rowsF}</tbody>\n</table>` : ''}\n<p>\u8a73\u7d30\u306f n8n \u5b9f\u884c\u5c65\u6b74\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002</p>`;\nreturn [{ json: { html, count: success.length, failed: failed.length } }];"
      },
      "id": "build-summary",
      "name": "Build Summary HTML",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2520,
        220
      ]
    },
    {
      "parameters": {
        "fromEmail": "manatsusuki@gmail.com",
        "toEmail": "={{ $('Config').item.json.notifyEmail }}",
        "subject": "=\u3010FANZA\u30ec\u30d3\u30e5\u30fc\u81ea\u52d5\u5316\u3011{{ $now.format('yyyy-MM-dd') }} \u4e0b\u66f8\u304d{{ $json.count }}\u4ef6",
        "html": "={{ $json.html }}",
        "options": {}
      },
      "id": "smtp-send",
      "name": "SMTP Send Summary",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        2740,
        220
      ],
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Schedule Trigger (Weekly Sun 03:00 JST)": {
      "main": [
        [
          {
            "node": "Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Config": {
      "main": [
        [
          {
            "node": "DMM API ItemList",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "DMM API ItemList": {
      "main": [
        [
          {
            "node": "Extract Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Items": {
      "main": [
        [
          {
            "node": "Build Claude Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Claude Prompt": {
      "main": [
        [
          {
            "node": "Claude Haiku API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude Haiku API": {
      "main": [
        [
          {
            "node": "Parse & Validate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse & Validate": {
      "main": [
        [
          {
            "node": "IF compliance pass",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF compliance pass": {
      "main": [
        [
          {
            "node": "WordPress Draft Post",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Failure Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "WordPress Draft Post": {
      "main": [
        [
          {
            "node": "Success Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Success Record": {
      "main": [
        [
          {
            "node": "Aggregate Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Failure Record": {
      "main": [
        [
          {
            "node": "Aggregate Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Success": {
      "main": [
        [
          {
            "node": "Build Summary HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Summary HTML": {
      "main": [
        [
          {
            "node": "SMTP Send Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveExecutionProgress": true,
    "saveManualExecutions": true,
    "timezone": "Asia/Tokyo"
  },
  "tags": [
    {
      "name": "fanza-auto-review"
    },
    {
      "name": "track-c"
    }
  ]
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

FANZA Review Auto-Generator (Phase 1). Uses httpRequest, emailSend. Scheduled trigger; 14 nodes.

Source: https://github.com/manatsusuki-claude/mana-pro/blob/b34feecc2f56dd437ec6c2eb61e81b4d8b5b2d94/n8n-workflows/fanza-auto-review/workflow.json — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

This workflow is an improvement of this workflow by Greg Brzezinka.

HTTP Request, Email Send, XML +1
Web Scraping

N8N-Self-Updater. Uses ssh, emailSend, httpRequest. Scheduled trigger; 27 nodes.

Ssh, Email Send, HTTP Request
Web Scraping

&gt; An automated n8n workflow originally built for DigitalOcean-based n8n deployments, but fully compatible with any VPS or cloud hosting (e.g., AWS, Google Cloud, Hetzner, Linode, etc.) where n8n ru

Ssh, Email Send, HTTP Request
Web Scraping

What if you could spot a major sales problem—or a winning campaign—the very next morning, instead of weeks later? Imagine receiving a beautiful, data-rich alert directly in your inbox the moment your

QuickBooks, HTTP Request, Email Send
Web Scraping

Track Changes Of Product Prices. Uses htmlExtract, functionItem, httpRequest, writeBinaryFile. Scheduled trigger; 25 nodes.

Html Extract, Function Item, HTTP Request +5