{
  "name": "Product board API proxy",
  "nodes": [
    {
      "parameters": {
        "respondWith": "allIncomingItems",
        "options": {}
      },
      "id": "f43d3189-bb80-402a-a3bb-6bc6fa774d01",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        1880,
        -160
      ]
    },
    {
      "parameters": {
        "fieldToSplitOut": "data",
        "options": {}
      },
      "id": "f9a47ee7-b27f-477d-8321-c1bf61ab343a",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        720,
        120
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "4eb647fc-4867-4af8-aae4-17db604bd3fa",
              "leftValue": "={{ $json.lastHealthUpdate }}",
              "rightValue": "=",
              "operator": {
                "type": "object",
                "operation": "exists",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "e2d90101-fcf5-476c-8a06-6bb676a077f6",
      "name": "Only take items with health",
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2,
      "position": [
        960,
        120
      ]
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "features",
        "include": "allFieldsExcept",
        "fieldsToExclude": "links,parent,description",
        "options": {}
      },
      "id": "40805b7c-834a-4f35-bf3a-e5dadcb8c0d2",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        1200,
        120
      ]
    },
    {
      "parameters": {
        "url": "={{ $json['links'] != null ? $json.links.next : \"https://api.productboard.com/features\" }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-Version",
              "value": "1"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('Features').item.json.headers['x-product-board-key'] }}"
            }
          ]
        },
        "options": {}
      },
      "id": "ab52906a-e25b-4ab5-b84f-499d733cbabd",
      "name": "Get features",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        20,
        100
      ]
    },
    {
      "parameters": {
        "jsCode": "let data = [], counter = 0, items;\ntry {\n  while ((items = $items(\"Get features\", 0, counter++).map(item => item.json.data)[0])) {\n    data.push(...items);\n  }\n} catch(error) {}\n  \nreturn [{json: {data}}];"
      },
      "id": "a1318cb7-53df-4469-8910-c0f4ec34bc33",
      "name": "Merge all features",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        500,
        120
      ]
    },
    {
      "parameters": {
        "jsCode": "let fields = {}, counter = 0, items;\n\ntry {\n  while ((items = $items(\"Get Fields\", 0, counter++).map(item => item.json.data)[0])) {\n    items.map(item => {\n      fields[item[\"hierarchyEntity\"][\"id\"]] ||= []\n      fields[item[\"hierarchyEntity\"][\"id\"]].push({\n        \"customFieldId\": item[\"customField\"][\"id\"],\n        \"value\": item[\"value\"][\"label\"],\n      });\n    });\n  }\n} catch(error) {}\n\nreturn [{json: {fields}}];"
      },
      "id": "0290f1e1-4c1f-4cae-9b5a-0f7a2224f9b9",
      "name": "Merge and Map Fields",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        500,
        420
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "f241314d-93a1-4eb1-b9de-bd4800fc09e3",
              "leftValue": "={{ $json.links.next }}",
              "rightValue": "=",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "813f4a85-b21a-45ba-b478-870a4b6a308a",
      "name": "More features?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        220,
        100
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "f241314d-93a1-4eb1-b9de-bd4800fc09e3",
              "leftValue": "={{ $json.links.next }}",
              "rightValue": "=",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "b152cbf4-528a-41fb-93c8-27c3a4ace32e",
      "name": "More fields?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        220,
        400
      ]
    },
    {
      "parameters": {
        "url": "={{ $json['links'] != null ? $json.links.next : \"https://api.productboard.com/hierarchy-entities/custom-fields-values?type=dropdown\" }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-version",
              "value": "1"
            },
            {
              "name": "authorization",
              "value": "=Bearer {{ $('Features').item.json.headers['x-product-board-key'] }}"
            }
          ]
        },
        "options": {}
      },
      "id": "7d1bdf32-e259-493a-a90d-2ddf36894538",
      "name": "Get Fields",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        20,
        400
      ]
    },
    {
      "parameters": {},
      "id": "c9ec6bc5-8ab0-4f67-9800-3ad26aef8df1",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 2.1,
      "position": [
        1460,
        400
      ]
    },
    {
      "parameters": {
        "jsCode": "let filteredFeatures = []\nlet features = $input.first().json.features;\nlet fields = $input.last().json.fields;\n\nlet RPMKey = \"f4754082-e2bd-4cd1-939c-2586b2137d4b\"\n\nfor (const feature of features) {\n  if(fields[ feature[\"id\"] ]) {\n    feature[\"customFields\"] = fields[ feature[\"id\"] ];\n    \n    let included = feature[\"customFields\"].some(obj => obj && obj[\"customFieldId\"] == RPMKey && obj[\"value\"] == \"Yes\")\n    \n    if(included) {   \n      // Rename API value to match UI value\n      if(feature.lastHealthUpdate && feature.lastHealthUpdate.status == \"needs-attention\") {\n        feature.lastHealthUpdate.status = \"at-risk\"\n      }\n\n      if( $('Features').first().json.query[\"issues\"] == \"true\" ) {\n        if(feature.lastHealthUpdate && (feature.lastHealthUpdate.status == \"at-risk\" || feature.lastHealthUpdate.status == \"off-track\") ) {\n          filteredFeatures.push(feature);\n        }\n        \n      } else {\n        filteredFeatures.push(feature);    \n      }\n            \n    }\n  }\n}\n\nreturn filteredFeatures;"
      },
      "id": "f1b77126-3bcf-4baf-bef3-8c9ca92acca7",
      "name": "Pick/Merge fields",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1700,
        400
      ]
    },
    {
      "parameters": {
        "url": "=https://api.productboard.com/features/{{ $json.params.id }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-version",
              "value": "1"
            },
            {
              "name": "authorization",
              "value": "=Bearer {{ $('Feature').item.json.headers['x-product-board-key'] }}"
            }
          ]
        },
        "options": {}
      },
      "id": "4fb585ec-797a-42ce-83c5-54835c70d64f",
      "name": "Get feature",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        20,
        -160
      ]
    },
    {
      "parameters": {
        "path": "/product-board/features/:id",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "b00b8067-6ee9-4eec-bf15-30f28cf0fc24",
      "name": "Feature",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1.1,
      "position": [
        -280,
        -160
      ]
    },
    {
      "parameters": {
        "path": "product-board/features",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "db7f2a61-632a-4406-bb28-c9261f79bb21",
      "name": "Features",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1.1,
      "position": [
        -280,
        100
      ]
    }
  ],
  "connections": {
    "Split Out": {
      "main": [
        [
          {
            "node": "Only take items with health",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Only take items with health": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get features": {
      "main": [
        [
          {
            "node": "More features?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge all features": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "More features?": {
      "main": [
        [
          {
            "node": "Get features",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge all features",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "More fields?": {
      "main": [
        [
          {
            "node": "Get Fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge and Map Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Fields": {
      "main": [
        [
          {
            "node": "More fields?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge and Map Fields": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Pick/Merge fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pick/Merge fields": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get feature": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Feature": {
      "main": [
        [
          {
            "node": "Get feature",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Features": {
      "main": [
        [
          {
            "node": "Get features",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "5e31169f-8be7-4e83-be2f-2790d0f0c22a",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "fj7lpiPRbAuv1x8h",
  "tags": [
    {
      "createdAt": "2024-04-09T14:24:57.191Z",
      "updatedAt": "2024-04-09T14:24:57.191Z",
      "id": "dhQnxaRmJScGFDZs",
      "name": "Product Board"
    },
    {
      "createdAt": "2024-04-04T13:00:30.639Z",
      "updatedAt": "2024-04-04T13:00:30.639Z",
      "id": "jWOhD5zFmjscKcRM",
      "name": "Webhook"
    }
  ]
}