Skip to content

Instantly share code, notes, and snippets.

@foeken
Last active April 15, 2024 06:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save foeken/cd9b75f967e033b29c6dd674df130e44 to your computer and use it in GitHub Desktop.
Save foeken/cd9b75f967e033b29c6dd674df130e44 to your computer and use it in GitHub Desktop.
Product Board ChatGPT Integration
{
"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
],
"webhookId": "3c873a6e-bedc-43a4-94d0-c80256307e75"
},
{
"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
],
"webhookId": "a745fff0-40a4-4637-a774-f6cc96980495"
}
],
"pinData": {},
"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,
"instanceId": "06a1587ad85c6277a08b3d3354a8e5a4d12576ac76d2916b2b45af6fc1e1164f"
},
"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"
}
]
}
{
"openapi": "3.1.0",
"info": {
"title": "ProductBoard API",
"description": "Access features / projects on the roadmap.",
"version": "v1.0.0"
},
"servers": [
{
"url": "N8N_URL/webhook"
}
],
"paths": {
"/3c873a6e-bedc-43a4-94d0-c80256307e75/product-board/features/{id}": {
"get": {
"description": "Get information about a specific feature / project",
"operationId": "GetFeature",
"parameters": [
{
"name": "id",
"in": "path",
"description": "The id of the feature / project",
"required": true,
"schema": {
"type": "string"
}
}
],
"deprecated": false
}
},
"/product-board/features": {
"get": {
"description": "Detail of all features / projects.",
"operationId": "Features",
"parameters": [
{
"name": "issues",
"in": "query",
"description": "Boolean to filter only the projects that are off-track or at-risk",
"required": false,
"schema": {
"type": "boolean"
}
}
],
"deprecated": false
}
}
},
"components": {
"schemas": {}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment