{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "c4e5be13-21a3-4801-8999-a5b04c4e7aa8",
      "name": "Get Latest WordPress Posts",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        928,
        576
      ],
      "parameters": {
        "url": "=https://www.mywordpresssite.com/wp-json/wp/v2/posts?status=publish&_embed=wp:featuredmedia",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "wordpressApi"
      },
      "credentials": {
        "wordpressApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "046ba645-ed8e-429d-968f-2f6dabab655b",
      "name": "Build Pin Payload from Post",
      "type": "n8n-nodes-base.set",
      "position": [
        1888,
        560
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "wp-post-id",
              "name": "post_id",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "wp-title",
              "name": "title",
              "type": "string",
              "value": "={{ $json.title.rendered.replace(/<[^>]*>/g, '').trim() }}"
            },
            {
              "id": "wp-description",
              "name": "description",
              "type": "string",
              "value": "={{ ($json.excerpt && $json.excerpt.rendered ? $json.excerpt.rendered.replace(/<[^>]*>/g, '').trim() : '').slice(0, 450) }}"
            },
            {
              "id": "wp-link",
              "name": "link_url",
              "type": "string",
              "value": "={{ $json.link }}"
            },
            {
              "id": "wp-image",
              "name": "image_url",
              "type": "string",
              "value": "={{ $json._links['wp:featuredmedia'][0].href }}"
            },
            {
              "id": "wp-alt",
              "name": "alt_text",
              "type": "string",
              "value": "={{ $json._links['wp:featuredmedia'][0].alt_text || $json.title.rendered.replace(/<[^>]*>/g, '').trim() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6714ee0a-89ae-4ee9-8b6e-2357c44ed602",
      "name": "Validate Required Fields",
      "type": "n8n-nodes-base.if",
      "position": [
        2128,
        560
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "has-title",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ !!$json.title }}",
              "rightValue": true
            },
            {
              "id": "has-description",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ !!$json.description }}",
              "rightValue": true
            },
            {
              "id": "has-link",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ !!$json.link_url }}",
              "rightValue": true
            },
            {
              "id": "has-image",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ !!$json.image_url }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8ab13a76-8445-42a3-a602-027df76f5fa3",
      "name": "Upload Image to PinBridge",
      "type": "n8n-nodes-pinbridge.pinBridge",
      "position": [
        2880,
        544
      ],
      "parameters": {
        "resource": "assets"
      },
      "credentials": {
        "pinBridgeApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "42ead53d-de04-4d88-bc04-1080291f5fca",
      "name": "Publish to Pinterest",
      "type": "n8n-nodes-pinbridge.pinBridge",
      "position": [
        3120,
        544
      ],
      "parameters": {
        "title": "={{ $('Build Pin Payload from Post').item.json.title }}",
        "altText": "={{ $('Build Pin Payload from Post').item.json.alt_text }}",
        "boardId": "1124281563167437941",
        "linkUrl": "={{ $('Build Pin Payload from Post').item.json.link_url }}?utm_source=pinterest&utm_medium=social",
        "accountId": "e3ebfe81-3854-4f56-a016-9e7fb4d7fcf7",
        "description": "={{ $('Build Pin Payload from Post').item.json.description }}",
        "dominantColor": "={{ $('Build Pin Payload from Post').item.json.dominant_color }}"
      },
      "credentials": {
        "pinBridgeApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "58122451-ba1c-4575-902f-b4b717b4ea5e",
      "name": "Build Success Result",
      "type": "n8n-nodes-base.set",
      "position": [
        3360,
        544
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "success-post-id",
              "name": "post_id",
              "type": "string",
              "value": "={{ $('Build Pin Payload from Post').item.json.post_id }}"
            },
            {
              "id": "success-title",
              "name": "title",
              "type": "string",
              "value": "={{ $('Build Pin Payload from Post').item.json.title }}"
            },
            {
              "id": "success-link",
              "name": "link_url",
              "type": "string",
              "value": "={{ $('Build Pin Payload from Post').item.json.link_url }}"
            },
            {
              "id": "success-job-id",
              "name": "job_id",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "success-status",
              "name": "status",
              "type": "string",
              "value": "submitted"
            },
            {
              "id": "success-timestamp",
              "name": "submitted_at",
              "type": "string",
              "value": "={{ $now }}"
            },
            {
              "id": "success-error",
              "name": "error_message",
              "type": "string",
              "value": ""
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a0e1e84b-821c-4ac7-b9ac-b571d4e54e6e",
      "name": "Build Invalid Result",
      "type": "n8n-nodes-base.code",
      "position": [
        2096,
        1024
      ],
      "parameters": {
        "jsCode": "return [{ json: { status: 'invalid', error_message: 'Post is missing one or more required fields: title, description, link_url, image_url', post_id: $json.post_id || '' } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "4c8987bd-ae1b-4411-88d9-f3aef5584385",
      "name": "Download Featured Image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2640,
        544
      ],
      "parameters": {
        "url": "={{ $('Get Latest WordPress Posts').item.json._embedded['wp:featuredmedia'][0].media_details.sizes.full.source_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "fa7c50c3-819f-4e23-aa6e-ecd617ebd868",
      "name": "List pins",
      "type": "n8n-nodes-pinbridge.pinBridge",
      "position": [
        448,
        576
      ],
      "parameters": {
        "operation": "list"
      },
      "credentials": {
        "pinBridgeApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c3f82872-68df-4c11-a4f7-c930fdf46f74",
      "name": "Published Titles",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        688,
        576
      ],
      "parameters": {
        "options": {},
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "fieldToAggregate": "title"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "1cfc59cd-f39c-45a1-8ce3-248f1564ac67",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        208,
        576
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "56ed507b-a60a-4520-a8f5-4f8cced117ce",
      "name": "Skip Posts Invalid Posts",
      "type": "n8n-nodes-base.if",
      "position": [
        1344,
        576
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "has-featured-media",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ !!$json._embedded && !!$json._embedded['wp:featuredmedia'] && !!$json._embedded['wp:featuredmedia'][0] && !!$json._embedded['wp:featuredmedia'][0].source_url && !$('Published Titles').first().json.title.includes($json.title.rendered.replace(/<[^>]*>/g, '').trim()) }}",
              "rightValue": true
            },
            {
              "id": "37df239c-9840-4e2c-a436-2ebdbcf893d2",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f7185abb-5066-4cf7-9a1d-3326d6e996a4",
      "name": "Sticky Note - Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        176,
        -256
      ],
      "parameters": {
        "color": 2,
        "width": 860,
        "height": 448,
        "content": "# Publish WordPress posts to Pinterest with duplicate protection\n\nThis template uses **WordPress as the content source**, **n8n as the orchestration layer**, and **PinBridge as the publishing layer**.\n\n### How it works\n1. Load existing PinBridge pins\n2. Aggregate their titles\n3. Fetch published WordPress posts\n4. Skip posts that are **invalid**\n5. Build a Pinterest-ready payload\n6. Validate the required fields\n7. Download the featured image\n8. Upload the image to PinBridge\n9. Submit the Pinterest publish job\n10. Return a structured success or invalid result\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4d9b6869-e0ad-4a6e-b211-c82d0eb418c2",
      "name": "Sticky Note - Setup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1088,
        -256
      ],
      "parameters": {
        "color": 2,
        "width": 760,
        "height": 440,
        "content": "## Setup checklist\n\nBefore running this workflow, replace placeholders and connect credentials:\n\n- Add a **WordPress** credential\n- Add a **PinBridge** credential\n- Replace `https://www.mywordpresssite.com`\n- Confirm the target **Pinterest account ID**\n- Confirm the target **board ID**\n- Confirm your WordPress REST API returns published posts with `_embed=wp:featuredmedia`\n\n\nThis workflow appends `?utm_source=pinterest&utm_medium=social` to the destination URL in the publish step for better analytics.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "8cf28038-8ece-4e54-9436-0c6a72a1dd6d",
      "name": "Sticky Note - Existing pins and source posts",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        176,
        304
      ],
      "parameters": {
        "color": 4,
        "width": 904,
        "height": 448,
        "content": "## Build the reference set and fetch source posts\n\n`List pins` loads existing PinBridge pins.\n\n`Published Titles` aggregates existing titles into a single list that the workflow uses as a lightweight duplicate-protection layer.\n\n`Get Latest WordPress Posts` then fetches published posts with embedded featured media from the WordPress REST API.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "8d76d1fe-ebc7-4e20-96d4-092ae32410eb",
      "name": "Sticky Note - Skip invalid posts",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1120,
        304
      ],
      "parameters": {
        "width": 588,
        "height": 448,
        "content": "## Skip invalid posts early\n\n`Skip Posts Invalid Posts` is the first protection layer.\n\nA post continues only when:\n- featured media exists with a usable source URL\n- the cleaned WordPress title is **not** already published by this workflow\n\nPosts that fail this check are treated as **invalid** and skipped.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "39b9567d-7b04-40d5-a103-5557900056af",
      "name": "Sticky Note - Build and validate payload",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1760,
        304
      ],
      "parameters": {
        "color": 6,
        "width": 668,
        "height": 456,
        "content": "## Build a publish-ready payload\n\n`Build Pin Payload from Post` maps WordPress data into:\n- `post_id` | `title` | `description` | `link_url` | `image_url` | `alt_text`\n\n\n`Validate Required Fields` then checks that the minimum publish fields are present before the workflow touches any external publish steps.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0c074d13-fce2-4db0-8441-9823ac2aafb5",
      "name": "Sticky Note - Publish path",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2512,
        304
      ],
      "parameters": {
        "color": 5,
        "width": 1048,
        "height": 452,
        "content": "## Valid posts: download, upload, submit\n\nFor valid posts, the workflow:\n1. Downloads the full-size featured image\n2. Uploads the image asset to PinBridge\n3. Submits the Pinterest publish job\n4. Builds a structured success result\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0a3e6072-9786-481f-9b7f-f5f8cd5007e3",
      "name": "Sticky Note - Invalid result branch",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2064,
        816
      ],
      "parameters": {
        "color": 3,
        "width": 540,
        "height": 376,
        "content": "## Invalid result branch\n\nIf required fields are missing after payload construction, `Build Invalid Result` returns a structured object instead of attempting submission.\n\nThis keeps incomplete content away from the publishing path and makes the workflow easier to review during testing.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "13067a5d-9d30-402c-88c1-ef41a182feb1",
      "name": "Sticky Note - Scope",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1872,
        -256
      ],
      "parameters": {
        "color": 2,
        "width": 708,
        "height": 448,
        "content": "## What this template covers\n\nThis template is intentionally scoped to:\n- list existing pins\n- fetch WordPress posts\n- skip invalid or already-published posts\n- submit new publish jobs\n- return structured results\n\n\nA separate workflow should handle webhook callbacks, final publish confirmation, retries, notifications, and reporting.\n"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "List pins": {
      "main": [
        [
          {
            "node": "Published Titles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "List pins",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Published Titles": {
      "main": [
        [
          {
            "node": "Get Latest WordPress Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Publish to Pinterest": {
      "main": [
        [
          {
            "node": "Build Success Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Featured Image": {
      "main": [
        [
          {
            "node": "Upload Image to PinBridge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Skip Posts Invalid Posts": {
      "main": [
        [
          {
            "node": "Build Pin Payload from Post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Required Fields": {
      "main": [
        [
          {
            "node": "Download Featured Image",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Invalid Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Image to PinBridge": {
      "main": [
        [
          {
            "node": "Publish to Pinterest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Latest WordPress Posts": {
      "main": [
        [
          {
            "node": "Skip Posts Invalid Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Pin Payload from Post": {
      "main": [
        [
          {
            "node": "Validate Required Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}