{
  "id": "SANITIZED_WORKFLOW_ID",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "37 - Productboard\u2013Linear Integration",
  "tags": [
    {
      "id": "SANITIZED_TAG_ID",
      "name": "Example",
      "createdAt": "2025-06-17T05:42:41.949Z",
      "updatedAt": "2025-06-17T05:42:41.949Z"
    }
  ],
  "nodes": [
    {
      "id": "460e03e8-4887-44fe-a7b9-22d054fc9667",
      "name": "\ud83d\udcc5 Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1520,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "439a1e13-f507-4852-9a82-54fdc93712e3",
      "name": "\ud83c\udf10 HTTP Request to ProductBoard",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1296,
        0
      ],
      "parameters": {
        "url": "https://api.productboard.com/features",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "X-Version",
              "value": "1"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "8951b0ae-f5c0-4f8e-950d-752345df1355",
      "name": "\ud83d\udcbb Code (Transform Features)",
      "type": "n8n-nodes-base.code",
      "position": [
        -1072,
        0
      ],
      "parameters": {
        "jsCode": "const rawData = items[0].json.data;\n\nconst result = rawData.map(d => {\n  return {\n    id: d.id,\n    name: d.name,\n    type: d.type,\n    status: d.status?.name || null,\n    parentId: d.parent?.feature?.id || d.parent?.component?.id || null,\n    owner: d.owner?.email || null,\n    description: d.description \n      ? d.description.replace(/<[^>]*>/g, '').trim() \n      : null,  // \u2705 plain text only\n    createdAt: d.createdAt ? new Date(d.createdAt).toISOString().split(\"T\")[0] : null,\n    updatedAt: d.updatedAt ? new Date(d.updatedAt).toISOString().split(\"T\")[0] : null,\n    link: d.links?.html || null,\n  };\n});\n\nreturn result.map(r => ({ json: r }));"
      },
      "typeVersion": 2
    },
    {
      "id": "040e657a-7b12-4a49-9e27-9368c3dbb28b",
      "name": "\u2696\ufe0f If (Filter New Features)",
      "type": "n8n-nodes-base.if",
      "position": [
        -848,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "bd7950c3-92a2-4b73-b806-58603d79ed42",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.createdAt }}",
              "rightValue": "={{ new Date($json.createdAt).toISOString().split(\"T\")[0] }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f7914171-83ce-4789-a531-a6e35bf0156f",
      "name": "\ud83d\udcdd Create Linear Issue",
      "type": "n8n-nodes-base.linear",
      "position": [
        -624,
        0
      ],
      "parameters": {
        "title": "={{ $json.name }}",
        "teamId": "YOUR_LINEAR_TEAM_ID",
        "additionalFields": {
          "description": "={{ $json.description }}"
        }
      },
      "credentials": {
        "linearApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "ad845fc6-1dc2-49c4-9531-72de9d5a86fd",
      "name": "\ud83d\udce2 Success Notification (Telegram)",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -400,
        0
      ],
      "parameters": {
        "text": "=\u2705 Successfully synced Productboard feature \"{{ $('\u2696\ufe0f If (Filter New Features)').item.json.name }}\" with Linear",
        "chatId": "YOUR_TELEGRAM_CHAT_ID",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c410712a-a467-4ee3-a1ad-cf2f5eb8f1a6",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1568,
        -496
      ],
      "parameters": {
        "color": 5,
        "width": 416,
        "height": 720,
        "content": "## \ud83d\uddd3 Trigger & Data Fetching\n\n*Schedule Trigger starts the workflow at defined intervals.\n\nHTTP Request (Productboard) fetches all features from Productboard using API authentication and version headers.\n\n\ud83d\udc49 Together, these nodes ensure Productboard data is regularly pulled in for syncing.*"
      },
      "typeVersion": 1
    },
    {
      "id": "e19527b8-f8b0-40ad-a999-46f60bc9c5b7",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1136,
        -496
      ],
      "parameters": {
        "width": 224,
        "height": 720,
        "content": "## \ud83d\udd04 Data Transformation\n\n*Code Node (Transform Features) processes the raw JSON from Productboard.\n\nStrips out HTML from feature descriptions \u2192 plain text only.\n\nExtracts key fields (id, name, type, status, parentId, owner, created/updated dates, link).\n\nFormats dates as YYYY-MM-DD.\n\n\ud83d\udc49 This guarantees that only clean, standardized data moves forward.*"
      },
      "typeVersion": 1
    },
    {
      "id": "4c17a6fb-67ec-41a9-8dd3-7fb931aede29",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -896,
        -496
      ],
      "parameters": {
        "color": 4,
        "width": 192,
        "height": 720,
        "content": "## \u2705 Filtering Logic\n\n*If Node (Filter New Features) compares the createdAt field against today's date.\n\nEnsures only newly created Productboard features proceed.\n\n\ud83d\udc49 Prevents duplicate syncing of older records.*"
      },
      "typeVersion": 1
    },
    {
      "id": "1f1286e7-81dc-41ab-a8c6-d63f5162eb49",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -688,
        -496
      ],
      "parameters": {
        "color": 3,
        "width": 432,
        "height": 720,
        "content": "## \ud83d\udcdd Issue Creation & Notifications\n\n*Create Linear Issue\n\nCreates a new issue in a specific Linear team.\n\nUses the Productboard feature name as the title and description as the issue body.\n\nTelegram Success Notification\n\nSends a confirmation message once a feature has been successfully synced into Linear.\n\n\ud83d\udc49 This closes the loop by syncing new Productboard features to Linear and notifying the team.*"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "SANITIZED_VERSION_ID",
  "connections": {
    "\ud83d\udcc5 Schedule Trigger": {
      "main": [
        [
          {
            "node": "\ud83c\udf10 HTTP Request to ProductBoard",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd Create Linear Issue": {
      "main": [
        [
          {
            "node": "\ud83d\udce2 Success Notification (Telegram)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcbb Code (Transform Features)": {
      "main": [
        [
          {
            "node": "\u2696\ufe0f If (Filter New Features)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u2696\ufe0f If (Filter New Features)": {
      "main": [
        [
          {
            "node": "\ud83d\udcdd Create Linear Issue",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83c\udf10 HTTP Request to ProductBoard": {
      "main": [
        [
          {
            "node": "\ud83d\udcbb Code (Transform Features)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}