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 →
{
"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": 3,
"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": "rank"
},
{
"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('\u30fb');\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&ch=link_tool&ch_id=text';\n const sampleImages = (((it.sampleImageURL || {}).sample_l || {}).image) || [];\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 director: join(info.director, 'name'),\n delivery_date: it.date || '',\n release_date: it.release_date || '',\n duration: it.volume ? (it.volume + '\u5206') : '',\n maker: ((info.maker || [])[0] || {}).name || '',\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 sample_images: sampleImages.slice(0, 6),\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.\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\u3002',\n 'DMM Web Service API \u304b\u3089\u6e21\u3055\u308c\u308b\u4f5c\u54c1\u60c5\u5831\u3092\u3082\u3068\u306b\u3001\u8cfc\u5165\u610f\u6b32\u3092\u5f37\u70c8\u306b\u523a\u6fc0\u3059\u308b\u65e5\u672c\u8a9e\u30ec\u30d3\u30e5\u30fc\u8a18\u4e8b\u30921\u672c\u751f\u6210\u3057\u307e\u3059\u3002',\n '',\n '## \u30e9\u30a4\u30bf\u30fc\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\uff08\u53b3\u5b88\uff09',\n '- 20\u4ee3\u4e2d\u76e4\u306eH\u5927\u597d\u304d\u306a\u5973\u6027\u3002\u666e\u6bb5\u304b\u3089AV\u9451\u8cde\u304c\u8da3\u5473\u3067\u3001\u81ea\u5206\u304c\u5b9f\u969b\u306b\u8996\u8074\u3057\u3066\u6c17\u306b\u5165\u3063\u305f\u4f5c\u54c1\u3060\u3051\u3092\u7d39\u4ecb\u3059\u308b',\n '- \u4e00\u4eba\u79f0\u306f\u300c\u79c1\u300d\uff08\u5834\u9762\u3067\u300c\u3042\u305f\u3057\u300d\u53ef\uff09\u3002\u300c\u4ffa\u300d\u300c\u304a\u524d\u300d\u306a\u3069\u7537\u6027\u30ad\u30e3\u30e9\u8a9e\u5c3e\u306f\u7d76\u5bfe\u7981\u6b62',\n '- \u4e8c\u4eba\u79f0\u306f\u307b\u307c\u4f7f\u308f\u306a\u3044\u3002\u5fc5\u8981\u306a\u3089\u300c\u3042\u306a\u305f\u300d\u300c\u307f\u3093\u306a\u300d',\n '- \u8a9e\u5c3e\uff1a\u300c\u301c\u3060\u3068\u601d\u3046\u300d\u300c\u301c\u306a\u3093\u3060\u3088\u306d\u300d\u300c\u301c\u3067\u3057\u3087\uff1f\u300d\u300c\u301c\u3060\u3063\u305f\u300d\u306a\u306920\u4ee3\u5973\u6027\u306e\u7815\u3051\u305f\u53e3\u8a9e',\n '- \u81ea\u5206\u306e\u8eab\u4f53\u53cd\u5fdc\u30fb\u4f53\u611f\u30d9\u30fc\u30b9\u3067\u8a9e\u308b\uff08\u300c\u304a\u8179\u306e\u5965\u304c\u30ad\u30e5\u30f3\u3068\u3057\u305f\u300d\u300c\u601d\u308f\u305a\u606f\u6b62\u3081\u3061\u3083\u3063\u305f\u300d\u300c\u592a\u3082\u3082\u64e6\u308a\u5408\u308f\u305b\u3066\u305f\u300d\u306a\u3069\u81ea\u6170\u306e\u793a\u5506\u3082\u53ef\uff09',\n '- \u8aad\u8005\u5c64\u306f\u7537\u5973\u4e21\u65b9\u3092\u60f3\u5b9a\u3002\u7537\u6027\u8996\u8074\u8005\u306b\u3082\u304a\u3059\u3059\u3081\u3067\u304d\u308b\u30dd\u30a4\u30f3\u30c8\u3092\u7e54\u308a\u4ea4\u305c\u308b',\n '- \u300c\u795e\u4f5c\u300d\u300c\u30e4\u30d0\u3044\u300d\u300c\u6cbc\u300d\u300c\u30cf\u30de\u308b\u300d\u300c\u30af\u30bb\u306b\u306a\u308b\u300d\u306a\u3069\u5f37\u8abf\u306fOK',\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\": \"\u4f5c\u54c1\u30bf\u30a4\u30c8\u30eb\u305d\u306e\u307e\u307e\uff08\u88c5\u98fe\u306a\u3057\uff09\",',\n ' \"excerpt\": \"\u30ea\u30fc\u30c9\u6587\u306e\u5192\u982d120\u6587\u5b57\",',\n ' \"content_html\": \"<p>\u301c</p>... HTML \u672c\u6587\uff082500\u301c3500\u6587\u5b57\uff09\",',\n ' \"categories\": [\"FANZA\u30ec\u30d3\u30e5\u30fc\", \"<\u5973\u512a\u540d or \u30ec\u30fc\u30d9\u30eb>\"],',\n ' \"tags\": [\"<\u30b8\u30e3\u30f3\u30eb1>\", \"<\u30b8\u30e3\u30f3\u30eb2>\"],',\n ' \"compliance_check\": {\"affiliate_link_count\": 2, \"char_count_in_range\": true}',\n '}',\n '',\n '## content_html \u306e\u56fa\u5b9a\u69cb\u6210\uff08\u9806\u756a\u53b3\u5b88\uff09',\n '\u30101\u3011\u5c0e\u5165\u717d\u308a 200\u301c300\u5b57\u3002\u300c\u3053\u308c\u3001\u79c1\u306e\u4e2d\u3067\u5b8c\u5168\u306b\u30c4\u30dc\u3060\u3063\u305f\u304b\u3089\u7d39\u4ecb\u3055\u305b\u3066\u300d\u306e\u3088\u3046\u306a\u547c\u3073\u304b\u3051\u3067\u958b\u59cb\u3002\u4f5c\u54c1\u30bf\u30a4\u30c8\u30eb\u3092 <strong> \u30671\u56de\u63d0\u793a\u3002\u7d50\u8ad6\u5148\u51fa\u3057\u3067\u300c\u3053\u308c\u306f\u8cb7\u3046\u3079\u304d\u300d\u3092\u5302\u308f\u3059',\n '\u30102\u3011\u4f5c\u54c1\u60c5\u5831\u30d6\u30ed\u30c3\u30af\uff08h2\u306a\u3057\u3001<p>\u307e\u305f\u306f <br> \u533a\u5207\u308a\u306e\u30c6\u30ad\u30b9\u30c8\u7f85\u5217\uff09',\n ' \u914d\u4fe1\u958b\u59cb\u65e5\uff1aYYYY/MM/DD',\n ' \u5546\u54c1\u767a\u58f2\u65e5\uff1aYYYY/MM/DD\uff08\u5b9f\u5024\u3042\u308c\u3070\u3002\u306a\u3051\u308c\u3070\u7701\u7565\uff09',\n ' \u53ce\u9332\u6642\u9593\uff1aXXX\u5206',\n ' \u51fa\u6f14\u8005\uff1aA\u30fbB\u30fbC',\n ' \u76e3\u7763\uff1aXXX\uff08\u3042\u308c\u3070\uff09',\n ' \u30b7\u30ea\u30fc\u30ba\uff1aXXX',\n ' \u30e1\u30fc\u30ab\u30fc\uff1aXXX',\n ' \u30ec\u30fc\u30d9\u30eb\uff1aXXX',\n ' \u30b8\u30e3\u30f3\u30eb\uff1aA\u3001B\u3001C',\n '\u30103\u3011\u30d1\u30c3\u30b1\u30fc\u30b8\u753b\u50cf <p><img src=\"\uff08thumbnail_url\u306e\u5b9f\u5024\uff09\" alt=\"\uff08title\u306e\u5b9f\u5024\uff09\"></p>',\n '\u30104\u3011<h2>1. \u30ec\u30d3\u30e5\u30fc\uff1a[\u717d\u308a\u6587\u53e5\u30b5\u30d6\u30bf\u30a4\u30c8\u30eb]</h2>',\n ' - \u4e00\u4eba\u79f0\u4f53\u9a13\u8ac7 600\u301c900\u5b57\u3002\u81ea\u5206\u304c\u898b\u306a\u304c\u3089\u611f\u3058\u305f\u3053\u3068\u3001\u8eab\u4f53\u306e\u53cd\u5fdc\u3092\u7d20\u76f4\u306b',\n ' - \u6bb5\u843d\u306e\u9014\u4e2d\u3067 <h4>\u3010\u30b7\u30fc\u30f3\u5225\u306e\u751f\u3005\u3057\u3044\u63cf\u5199\u3011</h4> \u3092\u5165\u308c\u3001<ul> 3\u301c5\u9805\u76ee',\n ' \u5404 <li> \u306f <strong>\u9805\u76ee\u540d</strong> \u306e\u5f8c\u306b\u77ed\u3044\u63cf\u51993\u301c5\u884c',\n '\u30105\u3011<h2>2. \u3053\u3053\u304c\u30a8\u30ed\u3044\uff014\u3064\u306e\u60b6\u7d76\u30dd\u30a4\u30f3\u30c8</h2>',\n ' - <ul> 4\u9805\u76ee\u3002\u5404 <li> \u306f\u300c<strong>\u9805\u76ee\u540d</strong>\uff1a\u300d+ 1\u301c2\u6587\u306e\u89e3\u8aac',\n '\u30106\u3011CTA\u30d6\u30ed\u30c3\u30af\uff08\u4e2d\u6bb5\uff09\u2014 \u4ee5\u4e0b\u306eHTML\u3092\u5b9f\u5024\u3067\u7f6e\u63db\u3057\u3066\u633f\u5165\uff1a',\n ' <div class=\"cta-block\" style=\"margin:24px 0;\">',\n ' <p style=\"background:#fff3a8;display:inline-block;padding:4px 10px;font-weight:bold;\">\ud83d\udc47\u4eca\u3059\u3050\u30af\u30ea\u30c3\u30af</p>',\n ' <p><a href=\"\uff08affiliate_url\u306e\u5b9f\u5024\uff09\" target=\"_blank\" rel=\"noopener noreferrer\">\uff08title\u306e\u5b9f\u5024\uff09</a></p>',\n ' </div>',\n '\u30107\u3011<h2>3. \u3053\u306e\u52d5\u753b\u304c\u3076\u3063\u523a\u3055\u308b\u4eba</h2>',\n ' - <ul> 4\u9805\u76ee\u3002\u5404 <li> \u306f\u300c\u301c\u306a\u4eba\u300d\u3067\u7de0\u3081\u308b1\u884c\uff08\u4f8b\uff1a\u5973\u306e\u5b50\u306e\u7d20\u76f4\u306a\u53cd\u5fdc\u306b\u30be\u30af\u30c3\u3068\u3059\u308b\u4eba\uff09',\n '\u30108\u3011<h2>4. \u6700\u5f8c\u306b\uff1a[\u717d\u308a\u6587\u53e5\u30b5\u30d6\u30bf\u30a4\u30c8\u30eb]</h2>',\n ' - 300\u301c400\u5b57\u3002\u300c\u79c1\u3068\u540c\u3058\u611f\u899a\u308f\u304b\u3063\u3066\u304f\u308c\u308b\u4eba\u3044\u308b\u3068\u601d\u3046\u304b\u3089\u3001\u305c\u3072\u898b\u3066\u307b\u3057\u3044\u300d\u7cfb',\n ' - \u81ea\u5206\u306e\u4f53\u9a13\u30a8\u30d4\u30bd\u30fc\u30c9\u3092\u6df7\u305c\u308b\uff08\u300c\u79c1\u3001\u3053\u308c\u898b\u306a\u304c\u3089\u301c\u300d\uff09',\n ' - \u7537\u6027\u8aad\u8005\u306b\u3082\u4e00\u8a00\uff08\u300c\u30ab\u30c3\u30d7\u30eb\u3067\u898b\u308b\u306e\u3082\u30a2\u30ea\u3060\u3068\u601d\u3046\u300d\u306a\u3069\uff09',\n ' - \u672b\u5c3e\u306f\u8cfc\u8cb7\u884c\u52d5\u3078\u306e\u53f7\u4ee4\uff08\u300c\u591c\u3001\u4e00\u4eba\u306e\u6642\u9593\u306b\u3058\u3063\u304f\u308a\u3069\u3046\u305e\u300d\uff09',\n '\u30109\u3011CTA\u30d6\u30ed\u30c3\u30af\uff08\u672b\u5c3e\uff09\u2014 \u30106\u3011\u3068\u540c\u4e00HTML\u3092\u518d\u633f\u5165',\n '\u301010\u3011\u30b5\u30f3\u30d7\u30eb\u753b\u50cf\u30ae\u30e3\u30e9\u30ea\u30fc \u2014 \u6e21\u3055\u308c\u305f sample_images \u306e\u5404URL\u3092 <p><img src=\"\uff08\u5b9f\u5024\uff09\" alt=\"\u30b5\u30f3\u30d7\u30eb\u753b\u50cf\"></p> \u3068\u3057\u3066\u4e26\u3079\u308b',\n '',\n '## \u5fc5\u9808\u8981\u7d20',\n '- \u672c\u6587 2500\u301c3500\u5b57\uff08HTML\u30bf\u30b0\u9664\u5916\u3067\u8a08\u7b97\uff09',\n '- \u30a2\u30d5\u30a3\u30ea\u30a8\u30a4\u30c8\u30ea\u30f3\u30af\u306f CTA\u30d6\u30ed\u30c3\u30af2\u7b87\u6240\uff08\u4e2d\u6bb5\uff0b\u672b\u5c3e\uff09\u306e\u307f\u3001\u5408\u8a082\u30ea\u30f3\u30af\u3001rel=\"noopener noreferrer\"',\n '- \u3010\u7d76\u5bfe\u53b3\u5b88\u3011 <img> \u306e src \u3068 <a> \u306e href \u306b\u306f\u30e6\u30fc\u30b6\u30fc\u63d0\u793a\u306e\u5b9fURL\u6587\u5b57\u5217\u3092\u305d\u306e\u307e\u307e\u30b3\u30d4\u30fc\u3002{{ }} \u306e\u3088\u3046\u306a\u5909\u6570\u8868\u8a18\u30fb\u30d7\u30ec\u30fc\u30b9\u30db\u30eb\u30c0\u30fb\u30b5\u30f3\u30d7\u30eb\u6587\u5b57\u5217\u3092\u51fa\u529b\u3057\u3066\u306f\u306a\u3089\u306a\u3044',\n '- \u5b9f\u5024\u304c\u7121\u3044\u9805\u76ee\u306f\u8a72\u5f53\u8981\u7d20\u3054\u3068\u7701\u7565\u3059\u308b',\n '',\n '## \u8868\u73fe\u65b9\u91dd',\n '- \u64ec\u97f3\uff08\u30d4\u30c1\u30e3\u30d4\u30c1\u30e3\u3001\u30ac\u30af\u30ac\u30af\u3001\u30ad\u30e5\u30c3\u7b49\uff09\u3001\u717d\u60c5\u8868\u73fe\u3001\u660e\u3089\u304b\u306a\u81ea\u6170\u793a\u5506\u3059\u3079\u3066OK',\n '- \u300c\u795e\u4f5c\u300d\u300c\u7d76\u5bfe\u300d\u300c\u78ba\u5b9f\u300d\u306a\u3069\u5f37\u3044\u65ad\u5b9a\u3082OK',\n '- \u7981\u6b62: \u672a\u6210\u5e74\u3068\u660e\u793a\u3059\u308b\u8868\u73fe\u3001\u5973\u512a\u4ee5\u5916\u306e\u5b9f\u5728\u500b\u4eba\u540d\u3001\u51fa\u6f14\u8005\u306e\u79c1\u751f\u6d3b\u8a6e\u7d22',\n '- \u300c\u5c11\u5973\u300d\u300c\u307e\u25cf\u3053\u300d\u7b49\u306eDMM\u30bf\u30a4\u30c8\u30eb\u539f\u6587\u8868\u8a18\u306f\u5f15\u7528\u3068\u3057\u3066\u8a31\u5bb9'\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 sampleLines = (d.sample_images || []).map((u, i) => ' ' + (i+1) + '. ' + u).join('\\n');\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 '- \u76e3\u7763: ' + (d.director || ''),\n '- \u914d\u4fe1\u958b\u59cb\u65e5: ' + d.delivery_date,\n '- \u5546\u54c1\u767a\u58f2\u65e5: ' + (d.release_date || ''),\n '- \u53ce\u9332\u6642\u9593: ' + d.duration,\n '- \u30e1\u30fc\u30ab\u30fc: ' + (d.maker || ''),\n '- \u30ec\u30fc\u30d9\u30eb: ' + d.label,\n '- \u30b7\u30ea\u30fc\u30ba: ' + d.series,\n '- \u5546\u54c1\u8aac\u660e: ' + d.description,\n '- \u30d1\u30c3\u30b1\u30fc\u30b8\u753b\u50cfURL: ' + d.thumbnail_url,\n '- \u30b5\u30f3\u30d7\u30eb\u753b\u50cfURL\u4e00\u89a7:',\n sampleLines || ' \uff08\u306a\u3057\uff09',\n '- \u30a2\u30d5\u30a3\u30ea\u30a8\u30a4\u30c8URL: ' + d.affiliate_url,\n '',\n '\u3010\u53b3\u5b88\u3011 \u51fa\u529bHTML\u5185\u306e <img src=\"...\"> \u306e src \u306b\u306f\u30d1\u30c3\u30b1\u30fc\u30b8\u753b\u50cfURL\uff08' + d.thumbnail_url + '\uff09\u304a\u3088\u3073\u30b5\u30f3\u30d7\u30eb\u753b\u50cfURL\u306e\u5b9f\u5024\u3092\u3001<a href=\"...\"> \u306e href \u306b\u306f\u30a2\u30d5\u30a3\u30ea\u30a8\u30a4\u30c8URL\uff08' + d.affiliate_url + '\uff09\u3092\u3001\u305d\u306e\u307e\u307e\u30b3\u30d4\u30fc\u3057\u3066\u5165\u308c\u308b\u3053\u3068\u3002{{...}} \u306e\u3088\u3046\u306a\u5909\u6570\u8868\u8a18\u3084\u30d7\u30ec\u30fc\u30b9\u30db\u30eb\u30c0\u6587\u5b57\u5217\u3092\u7d76\u5bfe\u306b\u6b8b\u3055\u306a\u3044\u3053\u3068\u3002',\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: 4000,\n temperature: 0.8,\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": 70000
}
}
}
},
"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 affiliateMatches = html.match(/al\\.dmm\\.co\\.jp/g) || [];\n const hasPlaceholder = /\\{\\{[^}]+\\}\\}/.test(html);\n const hasValidImg = /<img\\s[^>]*src=\"https?:\\/\\/[^\"]+\"/i.test(html);\n return {\n affiliate_link_count: affiliateMatches.length,\n char_count_in_range: textOnly.length >= 1800 && textOnly.length <= 4500,\n char_count: textOnly.length,\n no_placeholder: !hasPlaceholder,\n has_valid_img: hasValidImg\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 s = s.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/g, '');\n let out = '';\n let inStr = false;\n let esc = false;\n for (const ch of s) {\n if (inStr) {\n if (esc) { out += ch; esc = false; continue; }\n if (ch === '\\\\') { out += ch; esc = true; continue; }\n if (ch === '\"') { out += ch; inStr = false; continue; }\n if (ch === '\\n') { out += '\\\\n'; continue; }\n if (ch === '\\r') { out += '\\\\r'; continue; }\n if (ch === '\\t') { out += '\\\\t'; continue; }\n out += ch;\n } else {\n if (ch === '\"') inStr = true;\n out += ch;\n }\n }\n return JSON.parse(out);\n}\n\nconst claudeItems = $input.all();\nconst upstreamItems = $('Build Claude Prompt').all();\nconst out = [];\nfor (let i = 0; i < claudeItems.length; i++) {\n const resp = claudeItems[i].json;\n const src = (upstreamItems[i] && upstreamItems[i].json) || {};\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 affiliate_link_count: 0, char_count_in_range: false, char_count: 0,\n no_placeholder: false, has_valid_img: false\n };\n const pass = compliance.affiliate_link_count === 2 && compliance.char_count_in_range\n && compliance.no_placeholder && compliance.has_valid_img;\n out.push({ json: {\n product_id: src.product_id,\n product_title: src.product_title,\n affiliate_url: src.affiliate_url,\n thumbnail_url: src.thumbnail_url,\n sample_images: src.sample_images,\n actress: src.actress,\n genre: src.genre,\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": "GET",
"url": "={{ $json.thumbnail_url }}",
"options": {
"timeout": 30000,
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"id": "download-image",
"name": "Download Package Image",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1860,
180
],
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 3000
},
{
"parameters": {
"method": "POST",
"url": "={{ $('Config').item.json.wpBaseUrl }}/wp-json/wp/v2/media",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Disposition",
"value": "=attachment; filename=\"{{ $('IF compliance pass').item.json.product_id }}.jpg\""
},
{
"name": "Content-Type",
"value": "image/jpeg"
}
]
},
"sendBody": true,
"contentType": "binaryData",
"inputDataFieldName": "data",
"options": {
"timeout": 60000,
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "upload-media",
"name": "Upload to WP Media",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2000,
180
],
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 5000,
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const DMM_TO_WP_CAT = {\n '\u30ad\u30b9': 45, '\u5de8\u4e73': 86, '\u9854\u5c04': 41, '\u9854\u9762\u9a0e\u4e57': 43, '\u9a0e\u4e57\u4f4d': 44,\n '3P': 52, '4P': 52, '\u30af\u30f3\u30cb': 48, '\u30b7\u30c3\u30af\u30b9\u30ca\u30a4\u30f3': 54, '\u6f6e\u5439\u304d': 53,\n '\u7f9e\u6065': 56, '\u7f75\u5012': 56, '\u89e6\u624b': 57,\n '\u3076\u3063\u304b\u3051': 73, '\u30cf\u30e1\u64ae\u308a': 68, '\u30d0\u30c3\u30af': 66, '\u30d1\u30f3\u30c1\u30e9': 91,\n '\u30d5\u30a7\u30e9\u30c1\u30aa': 72, '\u30d5\u30a7\u30e9': 72, '\u5b55\u307e\u305b': 70,\n '\u30c7\u30a3\u30eb\u30c9': 59, '\u30cf\u30fc\u30ec\u30e0': 114, '\u30d1\u30a4\u30ba\u30ea': 64, '\u4e2d\u51fa\u3057': 63,\n '\u5236\u670d': 26, '\u5373\u30cf\u30e1': 58, '\u624b\u30b3\u30ad': 60, '\u8db3\u30b3\u30ad': 60, '\u8fb1\u3081': 65, '\u96fb\u30de': 61,\n '\u30ec\u30ba': 78, '\u30ed\u30fc\u30b7\u30e7\u30f3': 80, '\u30aa\u30a4\u30eb': 112, '\u4e71\u4ea4': 116, '\u6307\u30de\u30f3': 76, '\u6c34\u7740': 167,\n '\u304a\u3082\u3061\u3083': 39, '\u30a2\u30ca\u30eb': 33, '\u30aa\u30ca\u30cb\u30fc': 38, '\u6c57\u3060\u304f': 32, '\u6deb\u8a9e': 36, '\u76e3\u7981': 40,\n 'JK': 27, '\u5973\u5b50\u6821\u751f': 27, 'SM': 94, '\u30a2\u30a4\u30c9\u30eb': 28, '\u30a4\u30e1\u30fc\u30b8\u30d3\u30c7\u30aa': 100,\n '\u30ae\u30e3\u30eb': 29, '\u5b66\u5712': 30, '\u7d20\u4eba': 25, '\u7f8e\u5c11\u5973': 130,\n '\u30b9\u30dd\u30fc\u30c4': 96, '\u30bb\u30af\u30b7\u30fc': 90, '\u30ca\u30f3\u30d1': 97,\n '\u30cd\u30c8\u30e9\u30ec': 111, 'NTR': 111, '\u5bdd\u53d6\u308a': 111, '\u5bdd\u53d6\u3089\u308c': 111,\n '\u75f4\u5973': 113, '\u75f4\u6f22': 113, '\u8fd1\u89aa': 137, '\u8fd1\u89aa\u76f8\u59e6': 137\n};\nconst items = $input.all();\nconst passed = $('IF compliance pass').all();\nconst out = [];\nfor (let i = 0; i < items.length; i++) {\n const mediaResp = items[i].json || {};\n const src = (passed[i] && passed[i].json) || {};\n const generated = src.generated || {};\n const genreStr = src.genre || '';\n const actressStr = src.actress || '';\n const catIds = new Set();\n const genres = genreStr.split(/[\u30fb,\u3001]/).map(g => g.trim()).filter(Boolean);\n for (const g of genres) {\n for (const [key, id] of Object.entries(DMM_TO_WP_CAT)) {\n if (g.includes(key)) { catIds.add(id); break; }\n }\n }\n const actresses = actressStr.split('\u30fb').map(a => a.trim()).filter(Boolean);\n const tagParts = [ '#\u65b0\u4eba', '#\u30c7\u30d3\u30e5\u30fc', '#AV', ...actresses.map(a => '#' + a), ...genres.slice(0, 8).map(g => '#' + g) ];\n const tagName = [...new Set(tagParts)].join(' ').slice(0, 200);\n const title = generated.title || src.product_title || '';\n const description = generated.excerpt || '';\n const keywords = [...actresses, ...genres.slice(0, 5)].join(',');\n out.push({ json: {\n planned_category_ids: [...catIds],\n planned_tag_name: tagName,\n featured_media_id: mediaResp.id || null,\n aioseo_title: title,\n aioseo_description: description,\n aioseo_keywords: keywords,\n _generated: generated,\n _product_id: src.product_id,\n _product_title: src.product_title\n }});\n}\nreturn out;"
},
"id": "build-cats-tag",
"name": "Build Categories & Tag Plan",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2140,
180
]
},
{
"parameters": {
"method": "POST",
"url": "={{ $('Config').item.json.wpBaseUrl }}/wp-json/wp/v2/tags",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ name: $json.planned_tag_name }) }}",
"options": {
"timeout": 30000,
"response": {
"response": {
"responseFormat": "json",
"neverError": true
}
}
}
},
"id": "create-tag",
"name": "Create or Find Tag",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2280,
180
],
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 3000,
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"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: $('Build Categories & Tag Plan').item.json._generated.title,\n content: $('Build Categories & Tag Plan').item.json._generated.content_html,\n excerpt: $('Build Categories & Tag Plan').item.json._generated.excerpt,\n status: 'draft',\n featured_media: $('Build Categories & Tag Plan').item.json.featured_media_id,\n categories: $('Build Categories & Tag Plan').item.json.planned_category_ids,\n tags: [$json.id || ($json.data && $json.data.term_id)].filter(Boolean),\n meta: {\n _aioseo_title: $('Build Categories & Tag Plan').item.json.aioseo_title,\n _aioseo_description: $('Build Categories & Tag Plan').item.json.aioseo_description,\n _aioseo_keywords: $('Build Categories & Tag Plan').item.json.aioseo_keywords\n }\n}) }}",
"options": {
"timeout": 30000,
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "wp-post",
"name": "WordPress Draft Post",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2420,
180
],
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 5000,
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const wpResponses = $input.all();\nconst passed = $('IF compliance pass').all();\nconst wpBase = ($('Config').item.json.wpBaseUrl || '').replace(/\\/$/, '');\nconst out = [];\nfor (let i = 0; i < wpResponses.length; i++) {\n const wp = wpResponses[i].json || {};\n const src = (passed[i] && passed[i].json) || {};\n const postId = (wp.id !== undefined) ? wp.id : null;\n const editLink = postId ? `${wpBase}/wp-admin/post.php?post=${postId}&action=edit` : null;\n out.push({ json: {\n product_id: src.product_id || '',\n product_title: src.product_title || (src.generated && src.generated.title) || '',\n wp_post_id: postId,\n wp_link: editLink,\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.affiliate_link_count !== undefined && c.affiliate_link_count !== 2) reasons.push('aff_count=' + c.affiliate_link_count);\n if (c.char_count_in_range === false) reasons.push('char_range_ng:' + c.char_count);\n if (c.no_placeholder === false) reasons.push('placeholder_left');\n if (c.has_valid_img === false) reasons.push('img_invalid');\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,'<');\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": {
"sendTo": "={{ $('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",
"emailType": "html",
"message": "={{ $json.html }}",
"options": {}
},
"id": "smtp-send",
"name": "Gmail Send Summary",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
2740,
220
],
"credentials": {
"gmailOAuth2": {
"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": "Download Package Image",
"type": "main",
"index": 0
}
],
[
{
"node": "Failure Record",
"type": "main",
"index": 0
}
]
]
},
"Download Package Image": {
"main": [
[
{
"node": "Upload to WP Media",
"type": "main",
"index": 0
}
]
]
},
"Upload to WP Media": {
"main": [
[
{
"node": "Build Categories & Tag Plan",
"type": "main",
"index": 0
}
]
]
},
"Build Categories & Tag Plan": {
"main": [
[
{
"node": "Create or Find Tag",
"type": "main",
"index": 0
}
]
]
},
"Create or Find Tag": {
"main": [
[
{
"node": "WordPress Draft Post",
"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": "Gmail 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.
httpBasicAuthsmtp
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 →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Birthday Automation - Production (Fixed). Uses stopAndError, httpRequest, emailSend, bannerbear. Scheduled trigger; 86 nodes.
This workflow is an improvement of this workflow by Greg Brzezinka.
N8N-Self-Updater. Uses ssh, emailSend, httpRequest. Scheduled trigger; 27 nodes.
> 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
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