feat: add folder support for workflows (fixes #70)

This commit is contained in:
Praveen Mudalgeri
2025-08-05 09:40:47 +05:30
parent 307d530f9b
commit c4885eee92
2057 changed files with 985290 additions and 974268 deletions

View File

@@ -0,0 +1,582 @@
{
"meta": {
"instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "ad5b12df-3bdf-4672-99a7-0034664f29ef",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1180,
120
],
"parameters": {
"color": 4,
"width": 420.4803040774015,
"height": 189.69151356225348,
"content": "## Reply draft with OpenAI Assistant\nThis workflow automatically transfers content of incoming email messages with specific labels into OpenAI Assitant and returns reply draft. After draft is composed, trigger label is deleted from the thread.\n\n**Please remember to configure your OpenAI Assistant first.**"
},
"typeVersion": 1
},
{
"id": "80a93a48-0576-4dfb-817a-34cbc215307a",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-740,
120
],
"parameters": {
"width": 451.41125086385614,
"height": 313.3056033573073,
"content": "### Schedule trigger and get emails\nRun the workflow in equal intervals and check for threads with specific labels (trigger labels)."
},
"typeVersion": 1
},
{
"id": "0dba2603-8012-47d1-8c60-4068924b74cd",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1180,
340
],
"parameters": {
"color": 3,
"width": 421.0932411886662,
"height": 257.42916378714597,
"content": "## ⚠️ Note\n\n1. Complete video guide for this workflow is available [on my YouTube](https://youtu.be/a8Dhj3Zh9vQ). \n2. Remember to add your credentials and configure nodes (covered in the video guide).\n3. If you like this workflow, please subscribe to [my YouTube channel](https://www.youtube.com/@workfloows) and/or [my newsletter](https://workfloows.com/).\n\n**Thank you for your support!**"
},
"typeVersion": 1
},
{
"id": "4eb67d90-b834-48f6-8d8a-ed0a9d8321fd",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
520,
120
],
"parameters": {
"width": 381.6458068293894,
"height": 313.7892229150129,
"content": "### Generate reply\nTransfer email content to OpenAI Assitant and return AI-generated reply.\n"
},
"typeVersion": 1
},
{
"id": "fdb6e16b-5f42-4872-bf63-b18a14220cdf",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1160,
120
],
"parameters": {
"width": 219.88389496558554,
"height": 314.75072291501283,
"content": "### Create HTML message\nConvert incoming Markdown from OpenAI Assistant into HTML content."
},
"typeVersion": 1
},
{
"id": "111e4276-7f63-4b11-92be-fd9de7e23f05",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1400,
120
],
"parameters": {
"width": 461.3148409669012,
"height": 314.75072291501283,
"content": "### Build and encode message\nCreate raw message in RFC standard and encode it into base64 string (please see [Gmail API reference](https://developers.google.com/gmail/api/reference/rest/v1/users.drafts/create) for more details)."
},
"typeVersion": 1
},
{
"id": "0d377266-7fa2-43c4-9259-e8611d52df41",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
1880,
120
],
"parameters": {
"width": 219.88389496558554,
"height": 314.75072291501283,
"content": "### Insert reply draft\nAdd reply draft from OpenAI Assistant to specific Gmail thread."
},
"typeVersion": 1
},
{
"id": "c743486b-82e0-42f4-bd41-fad6115ac520",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
2120,
120
],
"parameters": {
"width": 219.88389496558554,
"height": 314.75072291501283,
"content": "### Remove label\nDelete trigger label from the Gmail thread."
},
"typeVersion": 1
},
{
"id": "dfe99c2e-a8e6-48de-a11d-54adaf98a7fe",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"width": 219.88389496558554,
"height": 314.75072291501283,
"content": "### Return message content\nRetrieve content of the last message in the thread."
},
"typeVersion": 1
},
{
"id": "6f228048-4067-494a-af44-080237c2555c",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
340
],
"parameters": {
"width": 470.88389496558545,
"height": 314.75072291501283,
"content": "### Get last message from thread\nReturn all messages for a single thread and pass for further processing only the last one."
},
"typeVersion": 1
},
{
"id": "bea0ea14-6198-4022-8ddc-a0c9f895d46e",
"name": "Remove AI label from email",
"type": "n8n-nodes-base.gmail",
"position": [
2180,
260
],
"webhookId": "f19c59fe-49bd-4661-aff3-a50e43e5964a",
"parameters": {
"resource": "thread",
"threadId": "={{ $('Map fields for further processing').item.json[\"threadId\"] }}",
"operation": "removeLabels"
},
"credentials": {
"gmailOAuth2": {
"id": "Sf5Gfl9NiFTNXFWb",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "dc9b5760-1669-4f29-b28d-73cd417775b4",
"name": "Add email draft to thread",
"type": "n8n-nodes-base.httpRequest",
"position": [
1940,
260
],
"parameters": {
"url": "https://www.googleapis.com/gmail/v1/users/me/drafts",
"method": "POST",
"options": {},
"jsonBody": "={\"message\":{\"raw\":\"{{ $json.encoded }}\", \"threadId\": \"{{ $('Map fields for further processing').item.json[\"threadId\"] }}\"}}",
"sendBody": true,
"specifyBody": "json"
},
"typeVersion": 4.2
},
{
"id": "dbbb607b-701f-49cd-b872-96522abde5b7",
"name": "Convert raw to base64",
"type": "n8n-nodes-base.code",
"position": [
1680,
260
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const encoded = Buffer.from($json.raw).toString('base64');\n\nreturn { encoded };"
},
"typeVersion": 2
},
{
"id": "9114d833-1c6a-47f1-bc8d-12fb8e17218e",
"name": "Build email raw",
"type": "n8n-nodes-base.set",
"position": [
1480,
260
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "6b6ece46-aeef-4ae5-9a0d-f472e7ced464",
"name": "raw",
"type": "string",
"value": "=To: {{ $json.to }}\nSubject: {{ $json.subject }}\nContent-Type: text/html; charset=\"utf-8\"\n\n{{ $json.response }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "67c1b6ca-d419-45a9-a1d5-2a6ac157454f",
"name": "Convert response to HTML",
"type": "n8n-nodes-base.markdown",
"position": [
1220,
260
],
"parameters": {
"mode": "markdownToHtml",
"options": {},
"markdown": "={{ $json.response }}"
},
"typeVersion": 1
},
{
"id": "97be72d7-20dd-4829-bf1c-f738fb6a8a21",
"name": "Map fields for further processing",
"type": "n8n-nodes-base.set",
"position": [
980,
260
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "d5022255-06d2-4322-b51e-ae80b7f6eef6",
"name": "response",
"type": "string",
"value": "={{ $json.output }}"
},
{
"id": "f729def0-3905-4c7d-ad1d-86ef7b001e9c",
"name": "threadId",
"type": "string",
"value": "={{ $('Get single message content').item.json[\"threadId\"] }}"
},
{
"id": "3ef18ad8-7328-4b97-bd6d-9d395a3c4a48",
"name": "to",
"type": "string",
"value": "={{ $('Get single message content').item.json[\"from\"][\"text\"] }}"
},
{
"id": "b013770d-fce2-4030-b372-8d94f04b51e9",
"name": "subject",
"type": "string",
"value": "={{ $('Get single message content').item.json[\"subject\"] }}"
},
{
"id": "69cc71b6-614d-4528-a598-69fbde1b5fd9",
"name": "messageId",
"type": "string",
"value": "={{ $('Get threads with specific labels').item.json[\"id\"] }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "545a4296-5307-42ee-8935-2886338e2518",
"name": "Ask OpenAI Assistant",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
580,
260
],
"parameters": {
"text": "={{ $json.text }}",
"prompt": "define",
"options": {},
"resource": "assistant",
"assistantId": {
"__rl": true,
"mode": "list",
"value": "asst_s32wsRpwU1HbLt40wRhghB6Y",
"cachedResultName": "Eva"
}
},
"credentials": {
"openAiApi": {
"id": "8gccIjcuf3gvaoEr",
"name": "OpenAi account"
}
},
"typeVersion": 1.8
},
{
"id": "4f326fec-e4bb-42dc-9f26-4a3d8ce86f24",
"name": "Get single message content",
"type": "n8n-nodes-base.gmail",
"position": [
60,
120
],
"webhookId": "1ddb410c-fcdd-4230-967a-cf7844727877",
"parameters": {
"messageId": "={{ $json.id }}",
"operation": "get"
},
"credentials": {
"gmailOAuth2": {
"id": "Sf5Gfl9NiFTNXFWb",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "faeb879f-db00-47b7-8995-9fb9025079cf",
"name": "Return last message in thread",
"type": "n8n-nodes-base.limit",
"position": [
280,
460
],
"parameters": {
"keep": "lastItems"
},
"typeVersion": 1
},
{
"id": "8085cb54-3c85-4450-9e42-825a9d467d6b",
"name": "Get thread messages",
"type": "n8n-nodes-base.gmail",
"position": [
60,
460
],
"webhookId": "d53aee55-4233-42e3-b0b7-2b4521956013",
"parameters": {
"options": {},
"resource": "thread",
"threadId": "={{ $json.id }}",
"operation": "get"
},
"credentials": {
"gmailOAuth2": {
"id": "Sf5Gfl9NiFTNXFWb",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "8a3c1885-8a05-4357-85ea-03cb9e8b24fa",
"name": "Loop over threads",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-200,
260
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "74197fae-823e-47bc-a1c9-b2fbe90b1171",
"name": "Get threads with specific labels",
"type": "n8n-nodes-base.gmail",
"position": [
-460,
260
],
"webhookId": "6b7faf91-cc60-482c-b661-dbd702cba2cc",
"parameters": {
"filters": {
"labelIds": []
},
"resource": "thread"
},
"credentials": {
"gmailOAuth2": {
"id": "Sf5Gfl9NiFTNXFWb",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "a3360f69-b8e6-4ef8-933a-352243ab9125",
"name": "Schedule trigger (1 min)",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-680,
260
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 1
}
]
}
},
"typeVersion": 1.2
}
],
"pinData": {},
"connections": {
"Build email raw": {
"main": [
[
{
"node": "Convert raw to base64",
"type": "main",
"index": 0
}
]
]
},
"Loop over threads": {
"main": [
[
{
"node": "Get single message content",
"type": "main",
"index": 0
}
],
[
{
"node": "Get thread messages",
"type": "main",
"index": 0
}
]
]
},
"Get thread messages": {
"main": [
[
{
"node": "Return last message in thread",
"type": "main",
"index": 0
}
]
]
},
"Ask OpenAI Assistant": {
"main": [
[
{
"node": "Map fields for further processing",
"type": "main",
"index": 0
}
]
]
},
"Convert raw to base64": {
"main": [
[
{
"node": "Add email draft to thread",
"type": "main",
"index": 0
}
]
]
},
"Convert response to HTML": {
"main": [
[
{
"node": "Build email raw",
"type": "main",
"index": 0
}
]
]
},
"Schedule trigger (1 min)": {
"main": [
[
{
"node": "Get threads with specific labels",
"type": "main",
"index": 0
}
]
]
},
"Add email draft to thread": {
"main": [
[
{
"node": "Remove AI label from email",
"type": "main",
"index": 0
}
]
]
},
"Get single message content": {
"main": [
[
{
"node": "Ask OpenAI Assistant",
"type": "main",
"index": 0
}
]
]
},
"Return last message in thread": {
"main": [
[
{
"node": "Loop over threads",
"type": "main",
"index": 0
}
]
]
},
"Get threads with specific labels": {
"main": [
[
{
"node": "Loop over threads",
"type": "main",
"index": 0
}
]
]
},
"Map fields for further processing": {
"main": [
[
{
"node": "Convert response to HTML",
"type": "main",
"index": 0
}
]
]
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,513 @@
{
"nodes": [
{
"id": "fc128eed-1666-46b8-8feb-e6ddf05e85d1",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
380,
240
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 2
}
]
}
},
"typeVersion": 1.2
},
{
"id": "830708eb-197b-4bf7-95da-893d78329ab2",
"name": "Strava",
"type": "n8n-nodes-base.strava",
"position": [
380,
480
],
"parameters": {
"limit": 10,
"operation": "getAll"
},
"typeVersion": 1.1
},
{
"id": "de776ebf-3ad5-4c4c-b0c8-7bc74cba5446",
"name": "Code",
"type": "n8n-nodes-base.code",
"position": [
380,
740
],
"parameters": {
"jsCode": "// Obtén los items del nodo \"Strava\"\nconst stravaItems = $('strava_last').all();\n\n// Obtén los items del nodo \"ultimas_id\"\nconst ultimasGuardadasItems = $('saved_last').all();\n\n// Extrae las referencias guardadas en un Set, asegurando el formato como cadena\nconst referenciasGuardadas = new Set(\n ultimasGuardadasItems.map(item => String(item.json.id))\n);\n\n// Filtra los items de \"Strava\" cuyos IDs no estén en las referencias guardadas\nconst filteredItems = stravaItems.filter(item => {\n // Convertir el ID actual de Strava a cadena para comparar correctamente\n return !referenciasGuardadas.has(String(item.json.id));\n});\n\n// Depuración: imprime las referencias y los resultados\nconsole.log('Referencias guardadas:', [...referenciasGuardadas]);\nconsole.log('Items filtrados:', filteredItems);\n\n// Devuelve los items filtrados\nreturn filteredItems;\n\n\n"
},
"typeVersion": 2
},
{
"id": "c8a93e6e-67fc-4f6d-bcde-83d3a885c622",
"name": "Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
900,
740
],
"parameters": {
"columns": {
"value": {
"Kms": "={{ $json.distancia }}",
"Ref": "={{ $json.id }}",
"Fecha": "={{ $json.fecha }}",
"Track": "=http://www.strava.com/activities/{{ $json.id }}",
"Tiempo": "={{ $json.tiempo }}",
"Desnivel": "={{ $json.elevacion }}"
},
"schema": [
{
"id": "Fecha",
"type": "string",
"display": true,
"required": false,
"displayName": "Fecha",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Kms",
"type": "string",
"display": true,
"required": false,
"displayName": "Kms",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Tiempo",
"type": "string",
"display": true,
"required": false,
"displayName": "Tiempo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Ref",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Ref",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Track",
"type": "string",
"display": true,
"required": false,
"displayName": "Track",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Bicicleta",
"type": "string",
"display": true,
"required": false,
"displayName": "Bicicleta",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Terreno",
"type": "string",
"display": true,
"required": false,
"displayName": "Terreno",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Desnivel",
"type": "string",
"display": true,
"required": false,
"displayName": "Desnivel",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": []
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 419561402,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/159k8cDL8hZooz-dsHE6ueWf68mBkHhxVCKnWm-lYLqs/edit#gid=419561402",
"cachedResultName": "n8n"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "159k8cDL8hZooz-dsHE6ueWf68mBkHhxVCKnWm-lYLqs",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/159k8cDL8hZooz-dsHE6ueWf68mBkHhxVCKnWm-lYLqs/edit?usp=drivesdk",
"cachedResultName": "Sherlo_Bike"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "tyg7FJlIITkSazyi",
"name": "Nik's Google"
}
},
"typeVersion": 4.5
},
{
"id": "0ce07d54-97af-4e88-9d27-452191a0b3ba",
"name": "strava_last",
"type": "n8n-nodes-base.set",
"position": [
1420,
480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "423ae4b8-287c-4dc1-b32b-d1b6f1f45efa",
"name": "id",
"type": "number",
"value": "={{ $json.id }}"
},
{
"id": "595802d2-17d0-40be-9e43-d655ffbf4ce0",
"name": "fecha",
"type": "string",
"value": "={{ DateTime.fromISO($json.start_date_local).toFormat('d/M/yyyy') }}"
},
{
"id": "4b39d783-19f2-4a7e-b0e6-dbe2b98f1ae0",
"name": "distancia",
"type": "number",
"value": "={{ Math.round($json.distance / 100) / 10 }}"
},
{
"id": "2f321dc0-435f-4b4d-866c-091ff9eaf9df",
"name": "elevacion",
"type": "number",
"value": "={{ Math.round($json.total_elevation_gain) }}"
},
{
"id": "ba1bb089-5ae7-4e42-ac65-07323c4e1842",
"name": "tiempo",
"type": "string",
"value": "={{ `${Math.floor($json.moving_time / 3600)}:${Math.floor(($json.moving_time % 3600) / 60).toString().padStart(2, '0')}:${($json.moving_time % 60).toString().padStart(2, '0')}` }}\n"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "490f7be9-73c9-4431-8b83-fcdbbcc283eb",
"name": "Remove Duplicates",
"type": "n8n-nodes-base.removeDuplicates",
"position": [
900,
480
],
"parameters": {
"compare": "selectedFields",
"options": {},
"fieldsToCompare": "id"
},
"typeVersion": 2
},
{
"id": "2d1c4dc5-2baa-4c89-a312-4b40381d4e5d",
"name": "activities",
"type": "n8n-nodes-base.googleSheets",
"position": [
660,
240
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 419561402,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/159k8cDL8hZooz-dsHE6ueWf68mBkHhxVCKnWm-lYLqs/edit#gid=419561402",
"cachedResultName": "n8n"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "159k8cDL8hZooz-dsHE6ueWf68mBkHhxVCKnWm-lYLqs",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/159k8cDL8hZooz-dsHE6ueWf68mBkHhxVCKnWm-lYLqs/edit?usp=drivesdk",
"cachedResultName": "Sherlo_Bike"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "tyg7FJlIITkSazyi",
"name": "Nik's Google"
}
},
"typeVersion": 4.5
},
{
"id": "2c7b7939-4ca1-4868-92bf-5fd7384a1103",
"name": "sort_saved",
"type": "n8n-nodes-base.sort",
"position": [
900,
240
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"fieldName": "Ref"
}
]
}
},
"typeVersion": 1
},
{
"id": "4e1d9064-6dda-4a01-af48-f278792f8b6b",
"name": "last_saved",
"type": "n8n-nodes-base.limit",
"position": [
1160,
240
],
"parameters": {
"keep": "lastItems",
"maxItems": 10
},
"typeVersion": 1
},
{
"id": "6eb2053a-1101-477b-86e9-113813be2d92",
"name": "saved_last",
"type": "n8n-nodes-base.set",
"position": [
1420,
240
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "50097932-ab91-4af7-9412-925fab1982f0",
"name": "id",
"type": "string",
"value": "={{ $json.Ref }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "afd986f1-0c49-4a69-b948-aefcbff1010f",
"name": "sort_strava",
"type": "n8n-nodes-base.sort",
"position": [
660,
480
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"fieldName": "id"
}
]
}
},
"typeVersion": 1
},
{
"id": "16094d29-f35b-492c-9d93-3145dab30cd3",
"name": "last_strava",
"type": "n8n-nodes-base.limit",
"position": [
1160,
480
],
"parameters": {
"keep": "lastItems",
"maxItems": 10
},
"typeVersion": 1
},
{
"id": "9986360b-fcd3-42f4-ad13-aea69f6d1a80",
"name": "sort_results",
"type": "n8n-nodes-base.sort",
"position": [
660,
740
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"fieldName": "id"
}
]
}
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"Code": {
"main": [
[
{
"node": "sort_results",
"type": "main",
"index": 0
}
]
]
},
"Strava": {
"main": [
[
{
"node": "sort_strava",
"type": "main",
"index": 0
}
]
]
},
"activities": {
"main": [
[
{
"node": "sort_saved",
"type": "main",
"index": 0
}
]
]
},
"last_saved": {
"main": [
[
{
"node": "saved_last",
"type": "main",
"index": 0
}
]
]
},
"saved_last": {
"main": [
[
{
"node": "Strava",
"type": "main",
"index": 0
}
]
]
},
"sort_saved": {
"main": [
[
{
"node": "last_saved",
"type": "main",
"index": 0
}
]
]
},
"last_strava": {
"main": [
[
{
"node": "strava_last",
"type": "main",
"index": 0
}
]
]
},
"sort_strava": {
"main": [
[
{
"node": "Remove Duplicates",
"type": "main",
"index": 0
}
]
]
},
"strava_last": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"sort_results": {
"main": [
[
{
"node": "Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "activities",
"type": "main",
"index": 0
}
]
]
},
"Remove Duplicates": {
"main": [
[
{
"node": "last_strava",
"type": "main",
"index": 0
}
]
]
}
}
}

View File

@@ -0,0 +1,920 @@
{
"meta": {
"instanceId": "03e9d14e9196363fe7191ce21dc0bb17387a6e755dcc9acc4f5904752919dca8"
},
"nodes": [
{
"id": "a9a92b8a-05cf-4d9e-ae01-be3b17346893",
"name": "Parse Webhook",
"type": "n8n-nodes-base.set",
"position": [
-560,
660
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "e63f9299-a19d-4ba1-93b0-59f458769fb2",
"name": "response",
"type": "object",
"value": "={{ $json.body.payload }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "f999011b-e54d-4514-94ec-4d544af4d145",
"name": "Close Modal Popup",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
-160,
1120
],
"parameters": {
"options": {},
"respondWith": "noData"
},
"typeVersion": 1.1
},
{
"id": "a16d64a0-fe07-4cae-b458-a91937e57a4e",
"name": "Route Message",
"type": "n8n-nodes-base.switch",
"position": [
-380,
660
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Request Modal",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.response.callback_id }}",
"rightValue": "search_recent_incidents"
}
]
},
"renameOutput": true
},
{
"outputKey": "Submit Data",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "65daa75f-2e17-4ba0-8fd8-2ac2159399e3",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.response.type }}",
"rightValue": "view_submission"
}
]
},
"renameOutput": true
},
{
"outputKey": "Block Actions",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "c242cee2-7274-4e02-bfbe-d0e999d30ea7",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.response.type }}",
"rightValue": "block_actions"
}
]
},
"renameOutput": true
}
]
},
"options": {
"fallbackOutput": "none"
}
},
"typeVersion": 3
},
{
"id": "54fa31d5-7259-4c19-8891-8b559af87959",
"name": "ServiceNow Modal",
"type": "n8n-nodes-base.httpRequest",
"position": [
260,
560
],
"parameters": {
"url": "https://slack.com/api/views.open",
"method": "POST",
"options": {},
"jsonBody": "= {\n \"trigger_id\": \"{{ $('Parse Webhook').item.json['response']['trigger_id'] }}\",\n \"external_id\": \"Search SNOW Incidents\",\n \"view\": {\n\t\"title\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Search SNOW Incidents\",\n\t\t\"emoji\": true\n\t},\n\t\"submit\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Search\",\n\t\t\"emoji\": true\n\t},\n\t\"type\": \"modal\",\n\t\"external_id\": \"search_snow_incidents\",\n\t\"close\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Cancel\",\n\t\t\"emoji\": true\n\t},\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"block_id\": \"greeting_section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \":wave: Hey there!\\n\\nUse this form to search ServiceNow for incidents based on their priority and state. Both of these properties are required to search incidents properly.\",\n\t\t\t\t\"emoji\": true\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\",\n\t\t\t\"block_id\": \"divider_1\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"priority_selector\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"external_select\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Priority of Incidents to Search\",\n\t\t\t\t\t\"emoji\": true\n\t\t\t\t},\n\t\t\t\t\"action_id\": \"priority_select\",\n\t\t\t\t\"min_query_length\": 0\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Priority Selector\",\n\t\t\t\t\"emoji\": true\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"state_selector\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"external_select\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"State of Incidents to Search\",\n\t\t\t\t\t\"emoji\": true\n\t\t\t\t},\n\t\t\t\t\"action_id\": \"state_select\",\n\t\t\t\t\"min_query_length\": 0\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"State Selector\",\n\t\t\t\t\"emoji\": true\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"Please select a channel where the results will be posted.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"actions\",\n\t\t\t\"elements\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"channels_select\",\n\t\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"text\": \"Select a channel\",\n\t\t\t\t\t\t\"emoji\": true\n\t\t\t\t\t},\n\t\t\t\t\t\"action_id\": \"actionId-1\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "slackApi"
},
"credentials": {
"slackApi": {
"id": "K04E2FxPZozHux9J",
"name": "ServiceNow Bot"
}
},
"typeVersion": 4.2
},
{
"id": "d16de218-b99b-4d13-9655-8fe1a329e01f",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-760,
660
],
"webhookId": "e03c7d39-1dce-4ac5-8db8-2b4511a85a07",
"parameters": {
"path": "e03c7d39-1dce-4ac5-8db8-2b4511a85a07",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "57ee358a-d409-42e7-8200-4475c4c59263",
"name": "Send 200",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
-160,
1660
],
"parameters": {
"options": {
"responseCode": 200
}
},
"typeVersion": 1.1
},
{
"id": "86b0fd85-b3d5-456c-8f59-0f29f283969f",
"name": "ServiceNow",
"type": "n8n-nodes-base.serviceNow",
"position": [
100,
1120
],
"parameters": {
"options": {
"sysparm_query": "=incident_state={{ $json.response.view.state.values.state_selector.state_select.selected_option.value }}^priority={{ $json.response.view.state.values.priority_selector.priority_select.selected_option.value }}",
"sysparm_display_value": "all"
},
"resource": "incident",
"operation": "getAll",
"returnAll": true,
"authentication": "basicAuth"
},
"credentials": {
"serviceNowBasicApi": {
"id": "wjkWiUNQxo5PzTIb",
"name": "ServiceNow Basic Auth account"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "95fcd7f1-ac3a-4128-8b4a-84b636487d9e",
"name": "Channel - Notify User no Incidents Matched",
"type": "n8n-nodes-base.slack",
"position": [
960,
1360
],
"webhookId": "5d1ecba8-d03b-47cc-9d30-fd631e7816c1",
"parameters": {
"text": "=No incidents were found with a state of {{ $('Parse Webhook').item.json.response.view.state.values.state_selector.state_select.selected_option.text.text }} and priority of {{ $('Parse Webhook').item.json.response.view.state.values.priority_selector.priority_select.selected_option.text.text }}.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Parse Webhook').item.json.response.view.state.values.pWqkN['actionId-1'].selected_channel }}"
},
"otherOptions": {
"includeLinkToWorkflow": false
}
},
"credentials": {
"slackApi": {
"id": "K04E2FxPZozHux9J",
"name": "ServiceNow Bot"
}
},
"typeVersion": 2.2
},
{
"id": "7f638817-6f97-42a9-9027-dd0d5fb6f560",
"name": "DM - Notify User no Incidents Matched",
"type": "n8n-nodes-base.slack",
"position": [
960,
1600
],
"webhookId": "5d1ecba8-d03b-47cc-9d30-fd631e7816c1",
"parameters": {
"text": "=No incidents were found with a state of {{ $('Parse Webhook').item.json.response.view.state.values.state_selector.state_select.selected_option.text.text }} and priority of {{ $('Parse Webhook').item.json.response.view.state.values.priority_selector.priority_select.selected_option.text.text }}.",
"user": {
"__rl": true,
"mode": "id",
"value": "={{ $('Parse Webhook').item.json.response.user.id }}"
},
"select": "user",
"otherOptions": {
"includeLinkToWorkflow": false
}
},
"credentials": {
"slackApi": {
"id": "K04E2FxPZozHux9J",
"name": "ServiceNow Bot"
}
},
"typeVersion": 2.2
},
{
"id": "f3a21223-9e74-4066-af9f-6b94f69cb01f",
"name": "Were Incidents Found?",
"type": "n8n-nodes-base.if",
"position": [
360,
1120
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "fcdf9a8e-6359-4a3e-bf4e-e1834945727b",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $('ServiceNow').item.json.number.value }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "e27438cb-ba24-4a3b-8fe8-52b7d39cb1e0",
"name": "No Matches - Was a Channel Selected?",
"type": "n8n-nodes-base.if",
"position": [
580,
1480
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a0b79298-b93f-4ed3-b53b-5c28dfdb2699",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $('Parse Webhook').item.json.response.view.state.values.pWqkN['actionId-1'].selected_channel }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "de7d3155-1c6d-43a1-9cc0-4900d176fd3e",
"name": "Sort by Most Recent",
"type": "n8n-nodes-base.sort",
"position": [
580,
580
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"order": "descending",
"fieldName": "number.value"
}
]
}
},
"typeVersion": 1
},
{
"id": "19f529c7-bfe6-4713-8ed3-d80ecc0078de",
"name": "Retain First 5 Incidents",
"type": "n8n-nodes-base.limit",
"position": [
740,
580
],
"parameters": {
"maxItems": 5
},
"typeVersion": 1
},
{
"id": "9b095ad5-dedc-43e6-9ab3-947b90e7145d",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
920,
580
],
"parameters": {
"options": {
"reset": false
}
},
"typeVersion": 3
},
{
"id": "9a236a69-3ea5-46f5-8f2d-f7421bff638a",
"name": "Format Incident Details",
"type": "n8n-nodes-base.set",
"position": [
1240,
680
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "62388dab-28d4-40fa-a9f9-90d68c5dc491",
"name": "incident_details",
"type": "string",
"value": "={\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"<https://dev206761.service-now.com/nav_to.do?uri=incident.do?sys_id={{ $json.sys_id.value }}|*{{ $json.task_effective_number.value }}*>\\n{{ $json.short_description.display_value }}\\n*Opened by:* {{ $json.caller_id.display_value }}\\n*Date Opened:* {{ $json.opened_at.display_value }}\\n*Severity:* {{ $json.severity.display_value }}\\n*Priority:* {{ $json.priority.display_value }}\\n*State:* {{ $json.incident_state.display_value }}\\n*Category:* {{ $json.category.display_value }}\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "6e15b991-d9d5-4244-a3db-dbd37c248303",
"name": "Format Slack Message",
"type": "n8n-nodes-base.set",
"position": [
1320,
500
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "90720996-88cc-4e47-b5bb-d5570c15f95c",
"name": "slack_output",
"type": "string",
"value": "={\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"block_id\": \"greeting_section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \":wave: Hey there!\\n\\nHere are the incident summaries you requested with a state of {{ $('Parse Webhook').item.json.response.view.state.values.state_selector.state_select.selected_option.text.text }} and priority of {{ $('Parse Webhook').item.json.response.view.state.values.priority_selector.priority_select.selected_option.text.text }}.\\nA total of {{ $('ServiceNow').all().length }} incident(s) were found. If more than 5 were found only the 5 most recent will be listed. You can <https://dev206761.service-now.com/now/nav/ui/classic/params/target/incident_list.do%3Fsysparm_query%3Dincident_state%253D{{ $('Parse Webhook').item.json.response.view.state.values.state_selector.state_select.selected_option.value }}%255Epriority%253D{{ $('Parse Webhook').item.json.response.view.state.values.priority_selector.priority_select.selected_option.value }}%26sysparm_first_row%3D1%26sysparm_view%3Dess|click here> to view all of the matching incidents in ServiceNow.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t},\n\t\t{{ $('Concatenate Incident Details').item.json.concatenated_incident_details }}\n\t]\n}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "08182589-800d-4ce6-8654-fc53d2ee56c3",
"name": "Concatenate Incident Details",
"type": "n8n-nodes-base.summarize",
"position": [
1140,
500
],
"parameters": {
"options": {},
"fieldsToSummarize": {
"values": [
{
"field": "incident_details",
"aggregation": "concatenate"
}
]
}
},
"typeVersion": 1
},
{
"id": "86b698d2-2854-4393-8ee8-76f8e7b01586",
"name": "DM - Send Matching Incidents",
"type": "n8n-nodes-base.slack",
"position": [
1880,
720
],
"webhookId": "5d1ecba8-d03b-47cc-9d30-fd631e7816c1",
"parameters": {
"text": "=",
"user": {
"__rl": true,
"mode": "id",
"value": "={{ $('Parse Webhook').item.json.response.user.id }}"
},
"select": "user",
"blocksUi": "={{ $('Format Slack Message').item.json.slack_output }}",
"messageType": "block",
"otherOptions": {
"includeLinkToWorkflow": false
}
},
"credentials": {
"slackApi": {
"id": "K04E2FxPZozHux9J",
"name": "ServiceNow Bot"
}
},
"typeVersion": 2.2
},
{
"id": "cbd8fbc3-d589-4625-99b5-a98e6a41d4bb",
"name": "Channel - Send Matching Incidents",
"type": "n8n-nodes-base.slack",
"position": [
1880,
520
],
"webhookId": "5d1ecba8-d03b-47cc-9d30-fd631e7816c1",
"parameters": {
"text": "=",
"select": "channel",
"blocksUi": "={{ $('Format Slack Message').item.json.slack_output }}",
"channelId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Parse Webhook').item.json.response.view.state.values.pWqkN['actionId-1'].selected_channel }}"
},
"messageType": "block",
"otherOptions": {
"includeLinkToWorkflow": false
}
},
"credentials": {
"slackApi": {
"id": "K04E2FxPZozHux9J",
"name": "ServiceNow Bot"
}
},
"typeVersion": 2.2
},
{
"id": "c3ed618f-b65e-4df2-80c0-90b2e2be3783",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
-200,
-709.4873251551015
],
"parameters": {
"color": 7,
"width": 709.3965558024038,
"height": 887.8719128264411,
"content": "![Slack](https://uploads.n8n.io/templates/servicenowmodalinterface.png)\n## Slack Modal Interface\n\nWhen triggered, Slack will display this interface to allow Slack users to search ServiceNow for tickets based on priority and state, and then allow you to choose which channel to output the results. If no channel is found, the response will be sent to the Slack user via DM. "
},
"typeVersion": 1
},
{
"id": "69f47cb7-84c6-4037-b3ba-8364ec572fde",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-798.751282964615,
190.55356752462308
],
"parameters": {
"color": 7,
"width": 579.6865154062818,
"height": 647.0013506366993,
"content": "![Slack](https://uploads.n8n.io/templates/slack.png)\n## Receive and Parse Slack Event via Webhook\n\nThis section begins with the `Webhook` node, which captures events from Slack, such as modal submissions or button presses. The payload from Slack is then processed by the `Parse Webhook` node to extract relevant details like callback IDs, user inputs (e.g., priority and state), and additional metadata. Once the data is parsed, it is passed to the `Route Message` node, which evaluates the callback ID or action type using a `Switch` node. Depending on the conditions, the workflow routes the data to specific paths: handling modal requests, processing data submissions, or responding to button actions. This setup ensures seamless handling of different Slack interactions and prepares the data for subsequent steps."
},
"typeVersion": 1
},
{
"id": "622f63e4-fd03-4a76-bb2d-04a2daea9a46",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
-200,
188.05676141451897
],
"parameters": {
"color": 7,
"width": 710.3172669178614,
"height": 563.0861092667175,
"content": "![Slack](https://uploads.n8n.io/templates/slack.png)\n## Respond to Modal request\n\nThis section starts with the `Respond to Slack Webhook`, which sends an acknowledgment to Slack after a modal interaction is triggered. This ensures the Slack interface remains error-free and provides a smooth user experience. Following this, the `ServiceNow Modal` node is used to open a Slack modal via the Slack API. The modal allows users to input search parameters for ServiceNow incidents, such as priority and state. Additionally, users can select the Slack channel where the results will be posted. This integration ensures a seamless connection between Slack and ServiceNow, enabling users to perform detailed searches directly from Slack.\n"
},
"typeVersion": 1
},
{
"id": "16d7f224-7792-4e9f-ae5c-1c0b6a39e703",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-200,
760
],
"parameters": {
"color": 7,
"width": 709.0896745965773,
"height": 550.5825149622945,
"content": "![Servicenow](https://uploads.n8n.io/templates/servicenow.png)\n## Close Modal and Search Service Now\n\nThis section starts with the `Close Modal Popup` node, which sends a response to Slack to close the modal after user input has been captured. Once the modal is closed, the workflow moves to the `ServiceNow` node. This node performs an API query to retrieve incidents from ServiceNow that match the specified state and priority provided by the user in the modal form. The query results are then evaluated by the `Were Incidents Found`? node, an If node that checks if any incidents were returned by the query. This section ensures a smooth transition from user input in Slack to backend data retrieval in ServiceNow, facilitating the identification of relevant incidents."
},
"typeVersion": 1
},
{
"id": "3f52816d-db59-4574-b82e-8a9ca854e049",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
526.5720643091352,
908.7025500703817
],
"parameters": {
"color": 7,
"width": 714.3631681325317,
"height": 911.8420872184945,
"content": "![Slack](https://uploads.n8n.io/templates/slack.png)\n## No Incidents found, respond to Slack\n\nThis section begins with the `No Matches - Was a Channel Selected?` node, which evaluates whether the user selected a specific Slack channel for receiving notifications. If a channel was selected, the workflow proceeds to the `Channel - Notify User no Incidents Matched` node, which sends a message to the designated channel informing users that no incidents were found matching the specified criteria of state and priority.\n\nIf no channel was selected, the workflow uses the `DM - Notify User no Incidents Matched` node to send a direct message to the user who initiated the query. This message includes details about the search parameters, ensuring the user is informed of the results regardless of the outcome. This step ensures transparent and efficient communication, whether via a public channel or a private direct message."
},
"typeVersion": 1
},
{
"id": "22943cc9-c79c-4465-ac9e-040d5f49a879",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-200,
1328.507039277291
],
"parameters": {
"color": 7,
"width": 709.4188646504804,
"height": 492.8100521251637,
"content": "![Slack](https://uploads.n8n.io/templates/slack.png)\n## Respond to Slack Button Press with 200 Response\n\nThis section uses the `Send 200` node to send a 200 HTTP response back to Slack whenever a button press event is triggered in a Slack message. This response is crucial for preventing Slack from showing errors in its Block Kit user interface, ensuring a seamless and professional interaction for the user. By handling these button press events gracefully, this step maintains a positive user experience and avoids unnecessary confusion or interruptions."
},
"typeVersion": 1
},
{
"id": "95d4d5e1-5f6b-4107-a55d-51e70c25c055",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
528.3624557345836,
26.66938195987973
],
"parameters": {
"color": 7,
"width": 956.6393374313541,
"height": 870.8771447693905,
"content": "![n8n](https://uploads.n8n.io/templates/n8n.png)\n## Sort and format Results for block kit\n\nThis section begins by organizing the incident data retrieved from ServiceNow. The `Sort by Most Recent` node arranges the incidents in descending order, ensuring that the latest ones are processed first. Next, the `Retain First 5 Incidents` node limits the output to the five most recent incidents for clarity and focus.\n\nThe `Loop Over Items` node iterates through each incident, allowing the workflow to process them individually. During each loop, the `Format Incident Details` node structures the details of each incident into a format compatible with Slacks Block Kit, ensuring readability and a professional appearance.\n\nOnce all incidents are formatted, the `Concatenate Incident Details` node aggregates the results into a single, cohesive message. Finally, the `Format Slack Message` node prepares the Slack message with a friendly greeting, summary details, and links to view the full incidents in ServiceNow. This section ensures that incident information is not only organized but also presented in a visually appealing and actionable manner within Slack."
},
"typeVersion": 1
},
{
"id": "2d55c76a-f7ba-46ec-acc1-13f54b22b2ee",
"name": "Was a Channel Selected?",
"type": "n8n-nodes-base.if",
"position": [
1580,
580
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a0b79298-b93f-4ed3-b53b-5c28dfdb2699",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $('Parse Webhook').item.json.response.view.state.values.pWqkN['actionId-1'].selected_channel }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "70792926-097f-4f2b-b3b4-afc7bad60ea6",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1500,
27.218710650838375
],
"parameters": {
"color": 7,
"width": 657.1120966423081,
"height": 870.9953951550463,
"content": "![Slack](https://uploads.n8n.io/templates/slack.png)\n## Check if Slack channel selected and send Incident results in block kit format\n\nThis section begins with the `Was a Channel Selected?` node, which checks whether the user specified a Slack channel to receive the output. If a channel is selected, the workflow proceeds to the `Channel - Send Matching Incidents` node, which sends the formatted incident details to the chosen Slack channel using Block Kit. The message includes key information such as incident summaries, priorities, and state details, ensuring effective communication to the target audience.\n\nIf no channel was selected, the workflow uses the `DM - Send Matching Incidents` node to deliver the same information directly to the user via a Slack direct message. By dynamically adjusting the delivery method based on the user's input, this step ensures the incident results are communicated efficiently, whether to a broader audience or privately to the user."
},
"typeVersion": 1
},
{
"id": "0ae7f5bf-7a78-42f6-95aa-c0f685e63c40",
"name": "Respond to Slack Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
-100,
560
],
"parameters": {
"options": {},
"respondWith": "noData"
},
"typeVersion": 1.1
}
],
"pinData": {},
"connections": {
"Webhook": {
"main": [
[
{
"node": "Parse Webhook",
"type": "main",
"index": 0
}
]
]
},
"ServiceNow": {
"main": [
[
{
"node": "Were Incidents Found?",
"type": "main",
"index": 0
}
]
]
},
"Parse Webhook": {
"main": [
[
{
"node": "Route Message",
"type": "main",
"index": 0
}
]
]
},
"Route Message": {
"main": [
[
{
"node": "Respond to Slack Webhook",
"type": "main",
"index": 0
}
],
[
{
"node": "Close Modal Popup",
"type": "main",
"index": 0
}
],
[
{
"node": "Send 200",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "Concatenate Incident Details",
"type": "main",
"index": 0
}
],
[
{
"node": "Format Incident Details",
"type": "main",
"index": 0
}
]
]
},
"Close Modal Popup": {
"main": [
[
{
"node": "ServiceNow",
"type": "main",
"index": 0
}
]
]
},
"Sort by Most Recent": {
"main": [
[
{
"node": "Retain First 5 Incidents",
"type": "main",
"index": 0
}
]
]
},
"Format Slack Message": {
"main": [
[
{
"node": "Was a Channel Selected?",
"type": "main",
"index": 0
}
]
]
},
"Were Incidents Found?": {
"main": [
[
{
"node": "Sort by Most Recent",
"type": "main",
"index": 0
}
],
[
{
"node": "No Matches - Was a Channel Selected?",
"type": "main",
"index": 0
}
]
]
},
"Format Incident Details": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Was a Channel Selected?": {
"main": [
[
{
"node": "Channel - Send Matching Incidents",
"type": "main",
"index": 0
}
],
[
{
"node": "DM - Send Matching Incidents",
"type": "main",
"index": 0
}
]
]
},
"Respond to Slack Webhook": {
"main": [
[
{
"node": "ServiceNow Modal",
"type": "main",
"index": 0
}
]
]
},
"Retain First 5 Incidents": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Concatenate Incident Details": {
"main": [
[
{
"node": "Format Slack Message",
"type": "main",
"index": 0
}
]
]
},
"No Matches - Was a Channel Selected?": {
"main": [
[
{
"node": "Channel - Notify User no Incidents Matched",
"type": "main",
"index": 0
}
],
[
{
"node": "DM - Notify User no Incidents Matched",
"type": "main",
"index": 0
}
]
]
}
}
}

View File

@@ -0,0 +1,562 @@
{
"meta": {
"instanceId": "=",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "bdc398f0-a882-4fbe-ac37-7ca7e15a1081",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2080,
-200
],
"parameters": {
"width": 460,
"height": 340,
"content": "![Tutorial](https://www.samirsaci.com/content/images/2025/04/temp-8.png)\n[🎥 Check My Tutorial](https://www.youtube.com/watch?v=LwTIro6Rapk)"
},
"typeVersion": 1
},
{
"id": "d132a584-770e-438c-bd98-28a9c1afa780",
"name": "When clicking Test workflow",
"type": "n8n-nodes-base.manualTrigger",
"position": [
1000,
120
],
"parameters": {},
"typeVersion": 1
},
{
"id": "d51eec9d-a177-4f5e-89e5-c73b6109f5ce",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
2100,
640
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "41da741b-1c1d-4d41-9a96-85cadacd1c8e",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1000,
-200
],
"parameters": {
"color": 7,
"width": 1040,
"height": 460,
"content": "### 1. First Block: audit the page to extract all the images with their respective alternative text\nThis workflow sends an HTTP request to collect the HTML processed by the Javascript node to list all the images in the page with their alternative texts. The results are saved in a Google Sheet.\n\n#### How to setup?\n- **Set your page link** in the first node\n- **Record the results in a Google Sheet Node**:\n 1. Add your Google Sheet API credentials to access the Google Sheet file\n 2. Select the file using the list, an URL or an ID\n 3. Select the sheet in which you want to record your working sessions\n 4. Map the fields\n [Learn more about the Google Sheet Node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets)\n"
},
"typeVersion": 1
},
{
"id": "e7a269cd-a2da-4ea9-9ec8-c023c45b9e96",
"name": "Page Link",
"type": "n8n-nodes-base.set",
"position": [
1200,
120
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "e69e5e68-5cd1-4f81-a940-2e5202d5589b",
"name": "url",
"type": "string",
"value": "https://www.samirsaci.com/sustainable-business-strategy-with-data-analytics/"
},
{
"id": "8839ac43-5d6a-4656-b555-714f836fc687",
"name": "baseUrl",
"type": "string",
"value": "https://www.samirsaci.com"
}
]
}
},
"notesInFlow": true,
"typeVersion": 3.4
},
{
"id": "6e6b7801-1f4c-4d00-826d-184dff58cee1",
"name": "Download Results",
"type": "n8n-nodes-base.googleSheets",
"position": [
1440,
640
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "=",
"value": "gid=0",
"cachedResultUrl": "=",
"cachedResultName": "="
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "=",
"cachedResultUrl": "=",
"cachedResultName": "="
}
},
"typeVersion": 4.5
},
{
"id": "1a137755-3f14-4881-93a5-db7f8678fa0d",
"name": "altLength < 50",
"type": "n8n-nodes-base.if",
"position": [
1660,
640
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a3b0ca70-0496-4966-94fd-f2927ce02ba9",
"operator": {
"type": "number",
"operation": "lt"
},
"leftValue": "={{ $json.altLength }}",
"rightValue": 100
}
]
}
},
"typeVersion": 2.2
},
{
"id": "60ea3935-313e-4d16-a8b8-a2fe7da8df82",
"name": "Limit records",
"type": "n8n-nodes-base.limit",
"position": [
1880,
560
],
"parameters": {
"maxItems": 5
},
"typeVersion": 1
},
{
"id": "5785deb6-1bf4-40a6-b556-42aad4c01c83",
"name": "Generate altText",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
2320,
560
],
"parameters": {
"text": "Please generate the alternative text (alt text) for this image under 150 characters.\t",
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-2024-05-13",
"cachedResultName": "GPT-4O-2024-05-13"
},
"options": {
"maxTokens": 150
},
"resource": "image",
"imageUrls": "={{ $('altLength < 50').item.json.src }}",
"operation": "analyze"
},
"notesInFlow": true,
"typeVersion": 1.8
},
{
"id": "86051a7f-e91a-4913-9c19-772673ff6306",
"name": "Update Results",
"type": "n8n-nodes-base.googleSheets",
"position": [
2540,
640
],
"parameters": {
"columns": {
"value": {
"page": "=",
"index": "={{ $('Loop Over Items').item.json.index }}",
"newAlt": "={{ $json.content }}"
},
"schema": [
{
"id": "index",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "index",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "page",
"type": "string",
"display": true,
"required": false,
"displayName": "page",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "src",
"type": "string",
"display": true,
"required": false,
"displayName": "src",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "alt",
"type": "string",
"display": true,
"required": false,
"displayName": "alt",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "altLength",
"type": "string",
"display": true,
"required": false,
"displayName": "altLength",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "newAlt",
"type": "string",
"display": true,
"required": false,
"displayName": "newAlt",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"index"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "=",
"cachedResultName": "="
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "=",
"cachedResultUrl": "=",
"cachedResultName": "="
}
},
"typeVersion": 4.5
},
{
"id": "b1ab97f7-a89e-40c8-ada3-22fcc6da2dcd",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1000,
320
],
"parameters": {
"color": 7,
"width": 1920,
"height": 520,
"content": "### 2. SecondBlock: generate alternative text for the image with altLength < 50\nThis workflow sends an HTTP request to collect the HTML processed by the Javascript node to list all the images in the page with their alternative texts. The results are saved in a Google Sheet.\n\n#### How to setup?\n- **Set your page link** in the first node\n- **Record the results in a Google Sheet Node**:\n 1. Add your Google Sheet API credentials to access the Google Sheet file\n 2. Select the file using the list, an URL or an ID\n 3. Select the sheet in which you want to record your working sessions\n 4. Map the fields\n [Learn more about the Google Sheet Node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets)\n"
},
"typeVersion": 1
},
{
"id": "c1bf1dcf-6789-43dd-9f15-29895c30fd23",
"name": "Store Results",
"type": "n8n-nodes-base.googleSheets",
"position": [
1860,
120
],
"parameters": {
"columns": {
"value": {
"alt": "={{ $json.alt }}",
"src": "={{ $json.src }}",
"page": "={{ $('Page Link').item.json.url }}",
"index": "={{ $json.index }}",
"altLength": "={{ $json.altLength }}"
},
"schema": [
{
"id": "index",
"type": "string",
"display": true,
"required": false,
"displayName": "index",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "page",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "page",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "src",
"type": "string",
"display": true,
"required": false,
"displayName": "src",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "alt",
"type": "string",
"display": true,
"required": false,
"displayName": "alt",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "altLength",
"type": "string",
"display": true,
"required": false,
"displayName": "altLength",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "newAlt",
"type": "string",
"display": true,
"required": false,
"displayName": "newAlt",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "=",
"cachedResultName": "="
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "=",
"cachedResultUrl": "=",
"cachedResultName": "="
}
},
"notesInFlow": true,
"typeVersion": 4.5
},
{
"id": "fe71094e-3a22-4cda-90ad-4174258a9086",
"name": "Download HTML",
"type": "n8n-nodes-base.httpRequest",
"position": [
1420,
120
],
"parameters": {
"url": "={{ $json.url }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "405fe4cf-5271-465c-8e2a-1f5d024228b6",
"name": "Get Images urls with altText",
"type": "n8n-nodes-base.code",
"position": [
1640,
120
],
"parameters": {
"jsCode": "const html = $input.first().json.data;\nconst baseUrl = $('Page Link').first().json.baseUrl;\n\nconst imgTagRegex = /<img\\b[^>]*>/gi;\nconst altAttrRegex = /alt\\s*=\\s*[\"']([^\"']*)[\"']/i;\nconst srcAttrRegex = /src\\s*=\\s*[\"']([^\"']*)[\"']/i;\n\nconst imageTags = html.match(imgTagRegex) || [];\n\nconst results = imageTags.map((tag, index) => {\n const altMatch = tag.match(altAttrRegex);\n const srcMatch = tag.match(srcAttrRegex);\n\n let alt = altMatch ? altMatch[1] : '[No alt text]';\n let src = srcMatch ? srcMatch[1] : '[No src]';\n\n // If src is relative, manually join with baseUrl\n if (src !== '[No src]' && !src.startsWith('http')) {\n if (baseUrl.endsWith('/') && src.startsWith('/')) {\n src = baseUrl + src.slice(1);\n } else if (!baseUrl.endsWith('/') && !src.startsWith('/')) {\n src = baseUrl + '/' + src;\n } else {\n src = baseUrl + src;\n }\n }\n\n return {\n index: index + 1,\n src,\n alt,\n altLength: alt.length,\n };\n});\n\nreturn results.map(item => ({ json: item }));"
},
"typeVersion": 2
}
],
"pinData": {},
"connections": {
"Page Link": {
"main": [
[
{
"node": "Download HTML",
"type": "main",
"index": 0
}
]
]
},
"Download HTML": {
"main": [
[
{
"node": "Get Images urls with altText",
"type": "main",
"index": 0
}
]
]
},
"Limit records": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Update Results": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"altLength < 50": {
"main": [
[
{
"node": "Limit records",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Generate altText",
"type": "main",
"index": 0
}
]
]
},
"Download Results": {
"main": [
[
{
"node": "altLength < 50",
"type": "main",
"index": 0
}
]
]
},
"Generate altText": {
"main": [
[
{
"node": "Update Results",
"type": "main",
"index": 0
}
]
]
},
"Get Images urls with altText": {
"main": [
[
{
"node": "Store Results",
"type": "main",
"index": 0
}
]
]
},
"When clicking Test workflow": {
"main": [
[
{
"node": "Page Link",
"type": "main",
"index": 0
},
{
"node": "Download Results",
"type": "main",
"index": 0
}
]
]
}
}
}

View File

@@ -0,0 +1,769 @@
{
"meta": {
"instanceId": "937602287d3b666a0823bdd18262071b517e6d94e73b786e71216e87cc17b79b",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "d74c545f-17ab-47f7-bb2a-93c9e9673bab",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
460,
-20
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 1,
"triggerAtMinute": 30
}
]
}
},
"typeVersion": 1.2
},
{
"id": "fc54b674-dc64-49ad-819d-66a4e416efc2",
"name": "Get all n8n Workflows",
"type": "n8n-nodes-base.n8n",
"position": [
680,
-20
],
"parameters": {
"filters": {},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "WR8oA7tQqdurDv3Y",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "b23cd260-8e68-42e7-935c-a658ae35cccd",
"name": "Backup to Google Drive2",
"type": "n8n-nodes-base.googleDrive",
"onError": "continueErrorOutput",
"position": [
1260,
400
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"options": {},
"operation": "update",
"changeFileContent": true,
"newUpdatedFileName": "={{ $('Workflow Data').item.json.name + \"_\" + $('Workflow Data').item.json.id+ \".json\"}}"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "FsjSbb8sdqbZm9dM",
"name": "Out"
}
},
"retryOnFail": true,
"typeVersion": 3
},
{
"id": "29a69d92-f416-489d-9a96-3a22844556e0",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
920,
-20
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "ddee56fd-8610-4cae-9ae0-76e58e7fd111",
"name": "Backup to Google Drive4",
"type": "n8n-nodes-base.googleDrive",
"onError": "continueErrorOutput",
"position": [
1380,
720
],
"parameters": {
"name": "={{ $('Workflow Data').item.json.name + \"_\" + $('Workflow Data').item.json.id+ \".json\"}}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "13clPf8pnv_-GLeeNXLhuVzQiqnKo_7Ev",
"cachedResultUrl": "https://drive.google.com/drive/folders/13clPf8pnv_-GLeeNXLhuVzQiqnKo_7Ev",
"cachedResultName": "n8nWorkflows"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "FsjSbb8sdqbZm9dM",
"name": "Out"
}
},
"retryOnFail": true,
"typeVersion": 3
},
{
"id": "8fdf83b1-5884-45a2-8710-e9012c07ccca",
"name": "ifDriveEmpty",
"type": "n8n-nodes-base.if",
"position": [
680,
420
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "5ec1b850-e0ce-4bd6-a8be-504e01825c00",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{$('getDriveFileData').item.json.name}}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "01437168-bb55-4308-a83c-a26c0f9c1843",
"name": "firstWorkflowJson",
"type": "n8n-nodes-base.set",
"position": [
1000,
720
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={{ $('Workflow Data').item.json.toJsonString() }}\n"
},
"typeVersion": 3.4
},
{
"id": "7bcb95db-b13b-4bef-9a34-acd1194f6d96",
"name": "JsonToFile",
"type": "n8n-nodes-base.code",
"position": [
1180,
720
],
"parameters": {
"jsCode": "return items.map(item => {\n const jsonData = JSON.stringify(item.json);\n const binaryData = Buffer.from(jsonData).toString('base64');\n item.binary = {\n data: {\n data: binaryData,\n mimeType: 'application/json',\n fileName: 'data.json'\n }\n };\n return item;\n});"
},
"typeVersion": 2
},
{
"id": "efdb7ea6-f4bf-4553-993c-448cd7bb2039",
"name": "CodeJsonToFile1",
"type": "n8n-nodes-base.code",
"position": [
1080,
400
],
"parameters": {
"jsCode": "return items.map(item => {\n const jsonData = JSON.stringify( $('Workflow Data').item.json);\n const binaryData = Buffer.from(jsonData).toString('base64');\n item.binary = {\n data: {\n data: binaryData,\n mimeType: 'application/json',\n fileName: 'data.json'\n }\n };\n return item;\n});"
},
"typeVersion": 2
},
{
"id": "411b1585-4be1-4a92-a54b-64965f0d529d",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
1100,
-40
],
"parameters": {},
"typeVersion": 1
},
{
"id": "dcd2e2ee-fc18-47bc-9210-b1b42c270961",
"name": "Workflow Data",
"type": "n8n-nodes-base.executionData",
"position": [
-140,
420
],
"parameters": {},
"typeVersion": 1
},
{
"id": "d243a474-9139-4af4-8134-df815a4af806",
"name": "successEmail",
"type": "n8n-nodes-base.gmail",
"position": [
1360,
-40
],
"webhookId": "b6cdbf4b-3abf-4eda-aa49-c19012e3133b",
"parameters": {
"sendTo": "your email address",
"message": "={{ $now.format('yyyy-MM-dd HH:mm') }} workflow backup success.",
"options": {},
"subject": "google drive workflow backup success",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "3QEYg96F002cbPmf",
"name": "out account"
}
},
"typeVersion": 2.1
},
{
"id": "306a1d38-27ef-4249-956a-cfec30d898b1",
"name": "failureEmail",
"type": "n8n-nodes-base.gmail",
"position": [
1620,
420
],
"webhookId": "f38fba13-3970-43a5-8afd-ea873289015b",
"parameters": {
"sendTo": "your email address",
"message": "={{ $now }} {{ $('Workflow Data').item.json.name }} workflow backup .",
"options": {},
"subject": "google drive workflow backup error",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "3QEYg96F002cbPmf",
"name": "out account"
}
},
"typeVersion": 2.1
},
{
"id": "544cb91c-4f96-4a84-8db2-9c88e758a1e3",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
600,
-80
],
"parameters": {
"color": 5,
"width": 260,
"height": 220,
"content": "## Set n8n API"
},
"typeVersion": 1
},
{
"id": "84d6b3e9-9f01-40b8-980d-acd2f95d30fe",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
600,
-180
],
"parameters": {
"color": 4,
"width": 150,
"height": 80,
"content": "## Edit this node 👇"
},
"typeVersion": 1
},
{
"id": "a3f1669b-41da-4256-af2c-e556738eabf1",
"name": "getDriveFileData",
"type": "n8n-nodes-base.googleDrive",
"position": [
300,
420
],
"parameters": {
"filter": {
"folderId": {
"__rl": true,
"mode": "url",
"value": "={{ $('Parameters').item.json.directory }}"
},
"whatToSearch": "files"
},
"options": {},
"resource": "fileFolder",
"returnAll": true,
"queryString": "={{ $('Workflow Data').item.json.name + \"_\" + $('Workflow Data').item.json.id+ \".json\"}}"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "FsjSbb8sdqbZm9dM",
"name": "Out"
}
},
"retryOnFail": true,
"typeVersion": 3,
"alwaysOutputData": true
},
{
"id": "f1771f9e-4153-4595-bbd9-22abfef23c54",
"name": "When Executed by Another Workflow",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
-300,
420
],
"parameters": {
"inputSource": "passthrough"
},
"typeVersion": 1.1
},
{
"id": "7110911a-c6c6-4ef6-888f-f640784d077b",
"name": "Execute Workflow",
"type": "n8n-nodes-base.executeWorkflow",
"position": [
1100,
100
],
"parameters": {
"options": {},
"workflowId": {
"__rl": true,
"mode": "id",
"value": "DfMF9CmVw6FU4hYm"
},
"workflowInputs": {
"value": {},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": true
}
},
"typeVersion": 1.2
},
{
"id": "cb5cc7fb-f24f-48be-a175-c24bf830dce2",
"name": "Parameters",
"type": "n8n-nodes-base.set",
"position": [
20,
420
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "1b65def6-4984-497d-a4bc-232af22927ad",
"name": "directory",
"type": "string",
"value": "https://drive.google.com/drive/folders/13clPf8pnv_-GLeeNXLhuVzQiqnKo_7Ev?usp=share_link"
},
{
"id": "c8c98f88-9f22-4574-88b8-1db99f6e4ec4",
"name": "parentdrive",
"type": "string",
"value": "https://drive.google.com/drive/u/0/my-drive"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "0ab79967-aa4e-4914-abbd-8a60057b083d",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-20,
300
],
"parameters": {
"color": 4,
"width": 150,
"height": 80,
"content": "## Edit this node 👇"
},
"typeVersion": 1
},
{
"id": "948c9276-88a7-4d02-85dc-525c4e8b0c01",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1240,
-100
],
"parameters": {
"width": 340,
"height": 220,
"content": "## Send complete message"
},
"typeVersion": 1
},
{
"id": "cabf9b91-5a2f-4c8f-ae07-318fca57b54f",
"name": "Discord",
"type": "n8n-nodes-base.discord",
"position": [
1360,
80
],
"webhookId": "65ce702c-8f03-4016-b192-a2503a7fbca7",
"parameters": {
"content": "={{ $now.format('yyyy-MM-dd HH:mm') }} Google Drive workflow backup success.",
"guildId": {
"__rl": true,
"mode": "list",
"value": ""
},
"options": {
"tts": false
},
"resource": "message",
"channelId": {
"__rl": true,
"mode": "list",
"value": "1365663078880116756",
"cachedResultUrl": "https://discord.com/channels/1365624783781494854/1365663078880116756",
"cachedResultName": "backup-status"
}
},
"credentials": {
"discordBotApi": {
"id": "hm4HwPUEF07pmkj0",
"name": "Discord Bot account"
}
},
"typeVersion": 2
},
{
"id": "ea46a8fb-5a43-400e-85d6-602ef1c68c5e",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
20,
-280
],
"parameters": {
"color": 7,
"width": 370,
"height": 480,
"content": "## 重要! 👇\n\n**啟動前: **\n\n### 作者資訊與資源\n作者Hochien Chang\nYouTube 頻道:[HC AI說人話](https://www.youtube.com/channel/UCvGfUB-wBdG4i_TdDGBCwJg)\n說明影片連結 https://youtu.be/PA15H5qunC0\n\n1. **更新認證:** 確認已設定「Google Drive OAuth2 API」認證。\n2. **設定參數:** 編輯「參數」節點,設定所需的 Google Drive 資料夾 URL。\n3. **設定電子郵件:** 使用您的收件者電子郵件地址更新「Gmail」節點。\n\n\n參考工作流https://n8n.io/workflows/3112-backup-n8n-workflows-to-google-drive/"
},
"typeVersion": 1
},
{
"id": "af7f9d0e-6ce4-4277-801d-92bf05a424d6",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-380,
-280
],
"parameters": {
"color": 7,
"width": 390,
"height": 480,
"content": "### IMPORTANT! 👇\n\n**Before activating:**\n### Author Information and Resources\nCreatorHochien Chang\nYouTube 頻道:[HC HumanizeAI](www.youtube.com/@HC-HumanizeAI)\nExplanation Video Link: https://youtu.be/PA15H5qunC0\n\n1. **Update Credentials:** Ensure 'Google Drive OAuth2 API' credentials are set up.\n2. **Configure Parameters:** Edit the 'Parameters' node to set your desired Google Drive folder URL.\n3. **Set Email:** Update the 'Gmail' nodes with your recipient email address.\n\n\nBase on: https://n8n.io/workflows/3112-backup-n8n-workflows-to-google-drive/"
},
"typeVersion": 1
},
{
"id": "f24c9b0c-1bf4-40dc-9492-8c452e5d9905",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
920,
600
],
"parameters": {
"color": 3,
"width": 620,
"height": 300,
"content": "## 新工作流上傳\n## New Workflow upload👇"
},
"typeVersion": 1
},
{
"id": "dac5bca9-9d7f-4131-a563-9115bf0528cc",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
920,
300
],
"parameters": {
"color": 6,
"width": 620,
"height": 280,
"content": "## 現有工作流更新\n## existing Workflow update👇"
},
"typeVersion": 1
},
{
"id": "6d126534-8b9b-4935-bce7-471ecc931e83",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
140,
300
],
"parameters": {
"width": 440,
"height": 280,
"content": "## 取得 Google Drive 現有的檔案資訊\n## Get Google Drive existing file info👇"
},
"typeVersion": 1
},
{
"id": "2ed623f4-faca-40ea-9ace-ab6d0933f6ba",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
580,
300
],
"parameters": {
"color": 4,
"width": 320,
"height": 280,
"content": "## 確認是否為第一次備份\n## Only for initialing👇"
},
"typeVersion": 1
},
{
"id": "46f0dbdc-4023-426c-b87b-3431817981c0",
"name": "Sticky Note14",
"type": "n8n-nodes-base.stickyNote",
"disabled": true,
"position": [
-380,
-380
],
"parameters": {
"color": 6,
"width": 760,
"height": 80,
"content": "# HC AI 說人話"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"Limit": {
"main": [
[
{
"node": "successEmail",
"type": "main",
"index": 0
},
{
"node": "Discord",
"type": "main",
"index": 0
}
]
]
},
"JsonToFile": {
"main": [
[
{
"node": "Backup to Google Drive4",
"type": "main",
"index": 0
}
]
]
},
"Parameters": {
"main": [
[
{
"node": "getDriveFileData",
"type": "main",
"index": 0
}
]
]
},
"ifDriveEmpty": {
"main": [
[
{
"node": "CodeJsonToFile1",
"type": "main",
"index": 0
}
],
[
{
"node": "firstWorkflowJson",
"type": "main",
"index": 0
}
]
]
},
"Workflow Data": {
"main": [
[
{
"node": "Parameters",
"type": "main",
"index": 0
}
]
]
},
"CodeJsonToFile1": {
"main": [
[
{
"node": "Backup to Google Drive2",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
],
[
{
"node": "Execute Workflow",
"type": "main",
"index": 0
}
]
]
},
"Execute Workflow": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get all n8n Workflows",
"type": "main",
"index": 0
}
]
]
},
"getDriveFileData": {
"main": [
[
{
"node": "ifDriveEmpty",
"type": "main",
"index": 0
}
]
]
},
"firstWorkflowJson": {
"main": [
[
{
"node": "JsonToFile",
"type": "main",
"index": 0
}
]
]
},
"Get all n8n Workflows": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Backup to Google Drive2": {
"main": [
[],
[
{
"node": "failureEmail",
"type": "main",
"index": 0
}
]
]
},
"Backup to Google Drive4": {
"main": [
[],
[
{
"node": "failureEmail",
"type": "main",
"index": 0
}
]
]
},
"When Executed by Another Workflow": {
"main": [
[
{
"node": "Workflow Data",
"type": "main",
"index": 0
}
]
]
}
}
}

View File

@@ -0,0 +1,509 @@
{
"id": "3JsfhcDcjqxx0hr3",
"meta": {
"instanceId": "38fb1860cc6284b8af9ba3b485f32cc1851cd97470ef1b4a472b5e707f1c93b5"
},
"name": "Extract And Decode Google News RSS URLs to Clean Article Links",
"tags": [
{
"id": "ROumyeVDIszTv7f5",
"name": "no-ai",
"createdAt": "2025-02-08T15:29:36.956Z",
"updatedAt": "2025-02-08T15:29:36.956Z"
},
{
"id": "XuoLgc5Eegoi3VEP",
"name": "scraping",
"createdAt": "2025-01-31T18:19:12.753Z",
"updatedAt": "2025-01-31T18:19:12.753Z"
},
{
"id": "nBHkkAND8NXbkg8m",
"name": "news",
"createdAt": "2025-03-13T15:47:18.420Z",
"updatedAt": "2025-03-13T15:47:18.420Z"
}
],
"nodes": [
{
"id": "cdb0a726-e961-40ae-b679-43f7bd73650d",
"name": "When clicking Test workflow",
"type": "n8n-nodes-base.manualTrigger",
"position": [
560,
1240
],
"parameters": {},
"typeVersion": 1
},
{
"id": "028ddd3b-069c-43be-ad56-8f898805fccf",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
1040,
1000
],
"parameters": {
"maxItems": 5
},
"typeVersion": 1
},
{
"id": "2215bfdc-1e6e-475c-9753-b05fd5b0d63a",
"name": "Reading Google News RSS",
"type": "n8n-nodes-base.rssFeedRead",
"position": [
840,
1000
],
"parameters": {
"url": "https://news.google.com/rss?hl=it&gl=IT&ceid=IT:it",
"options": {
"ignoreSSL": false
}
},
"typeVersion": 1.1
},
{
"id": "23b50dac-9506-41cb-8b57-15373468ab3c",
"name": "Decoded url",
"type": "n8n-nodes-base.set",
"position": [
1520,
1420
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c51f320e-4fb8-4bd4-8e36-9330e251936e",
"name": "google_news_url",
"type": "string",
"value": "={{ JSON.parse(JSON.parse($json.data.split('\\n\\n')[1])[0][2])[1] }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "40f54966-41c7-4dc3-95ac-18b8eaffe1db",
"name": "Call decoding URL",
"type": "n8n-nodes-base.httpRequest",
"position": [
1280,
1420
],
"parameters": {
"url": "https://news.google.com/_/DotsSplashUi/data/batchexecute",
"method": "POST",
"options": {
"response": {
"response": {
"fullResponse": true,
"responseFormat": "text"
}
}
},
"sendBody": true,
"contentType": "form-urlencoded",
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "f.req",
"value": "={{ $json.f_req }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/x-www-form-urlencoded;charset=UTF-8"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
},
{
"name": "Referer",
"value": "https://www.google.com/"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "e7a208d3-bf65-4170-bb11-d13287f8dd78",
"name": "Prepare decoding variables",
"type": "n8n-nodes-base.code",
"position": [
1040,
1420
],
"parameters": {
"jsCode": "return $input.all().map(item => {\n const gn_art_id = item.json.base64Str;\n const timestamp = item.json.timestamp;\n const signature = item.json.signature;\n\n const articlesReq = [\n 'Fbv4je',\n `[\"garturlreq\",[[\"X\",\"X\",[\"X\",\"X\"],null,null,1,1,\"US:en\",null,1,null,null,null,null,null,0,1],\"X\",\"X\",1,[1,1,1],1,1,null,0,0,null,0],\"${gn_art_id}\",${timestamp},\"${signature}\"]`,\n ];\n\n return {\n json: {\n f_req: JSON.stringify([[articlesReq]]) // Questo verrà usato nel nodo HTTP Request\n }\n };\n});"
},
"typeVersion": 2
},
{
"id": "35fe85f1-82c7-4b50-b47b-14c56678e377",
"name": "Get encoded news URL",
"type": "n8n-nodes-base.httpRequest",
"position": [
1280,
1000
],
"parameters": {
"url": "={{ $('Limit').item.json.link }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "3d640138-4247-4e6d-a0e9-fefc9f41e057",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
740,
760
],
"parameters": {
"width": 220,
"height": 400,
"content": "## Get Google News\n\nChange the language parameters on ISO639-1 standard \n\n1. hl=it\n2. gl=IT\n3. ceid=IT:it"
},
"typeVersion": 1
},
{
"id": "1e7a5638-8829-49f1-a445-f510eb18bbd7",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
980,
760
],
"parameters": {
"width": 220,
"height": 400,
"content": "## Limit result\n\nI suggest limiting the results to a maximum of 3 because the entire workflow makes a lot of HTTP requests"
},
"typeVersion": 1
},
{
"id": "24a405df-c334-461a-ab0d-91ebc39185c1",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
500,
760
],
"parameters": {
"color": 5,
"width": 220,
"height": 820,
"content": "## INFO\n\nDisclaimer:\nYou can add a cron trigger but... don't do too often: Google could block your ip.\n\nThis workflow works until works: the decoding procedure is hardcoded and based on reverse engineering. Requests and responses are not documented by Google.\n\n\n"
},
"typeVersion": 1
},
{
"id": "c54e9729-7cbd-4628-b7be-ee072047b3d4",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1220,
760
],
"parameters": {
"color": 3,
"width": 220,
"height": 400,
"content": "## Get encoded content\n\nHere we retrieve HTML content"
},
"typeVersion": 1
},
{
"id": "a5b25d20-0d06-4650-b8bc-0d03c97eb416",
"name": "Map needed keys",
"type": "n8n-nodes-base.set",
"position": [
780,
1420
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "b5a11795-2bd1-412f-a215-f7402bece002",
"name": "signature",
"type": "string",
"value": "={{ $json.signature }}"
},
{
"id": "33267283-3ac8-4d65-9a01-c7f154a7d061",
"name": "timestamp",
"type": "string",
"value": "={{ $json.timestamp }}"
},
{
"id": "bff8f19a-30d6-4307-87da-9b98b26cee8b",
"name": "base64Str",
"type": "string",
"value": "={{ $('Limit').item.json.guid }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "116eec84-dbfe-4880-8fc4-d350ff99d4be",
"name": "Extract decoding keys",
"type": "n8n-nodes-base.html",
"position": [
1520,
1000
],
"parameters": {
"options": {},
"operation": "extractHtmlContent",
"extractionValues": {
"values": [
{
"key": "signature",
"attribute": "data-n-a-sg",
"cssSelector": "div",
"returnValue": "attribute"
},
{
"key": "timestamp",
"attribute": "data-n-a-ts",
"cssSelector": "div",
"returnValue": "attribute"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "22825293-d9f8-4fa2-99b4-2150a74b2a12",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1460,
760
],
"parameters": {
"width": 220,
"height": 400,
"content": "## Decoding Keys\n\nThe HTML content extracted contains the necessary variables for decoding:\n\n+ signature\n+ timestamp\n+ base64string (already in the URL)"
},
"typeVersion": 1
},
{
"id": "46dce5e2-1c4f-45d8-a849-ebe13d673ef9",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
740,
1180
],
"parameters": {
"width": 220,
"height": 400,
"content": "## Clean output\n\nMapping variables for easy utilization"
},
"typeVersion": 1
},
{
"id": "9dbc9f69-d34a-470e-81af-c3bcc9a92a48",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
980,
1180
],
"parameters": {
"color": 3,
"width": 220,
"height": 400,
"content": "## Preparing Request\n\nDecoding the request requires specific body content. Here, we build it using the decoding keys."
},
"typeVersion": 1
},
{
"id": "39a492a7-a099-4ae7-ac17-d3842f0682fe",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
1220,
1180
],
"parameters": {
"color": 3,
"width": 220,
"height": 400,
"content": "## This is decoding step\n\nSending a request to a specific Google decoding URL"
},
"typeVersion": 1
},
{
"id": "29d3b1a3-5882-484d-9add-68a746f0a7b8",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
1460,
1180
],
"parameters": {
"width": 220,
"height": 400,
"content": "## Cleaning URL\n\nGoogle adds some unwanted and random characters at the beginning of the URL"
},
"typeVersion": 1
},
{
"id": "6b2fc671-2a22-4a6d-bcc5-38294981d9fe",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1700,
760
],
"parameters": {
"color": 4,
"width": 220,
"height": 820,
"content": "## OUTPUT\n\nA lot of requests are made before getting clean News URLs.\n\nYou can add an HttpRequest and get News text with jina.ai, extract by using HTML node, or a custom node like https://www.npmjs.com/package/n8n-nodes-webpage-content-extractor\n\n"
},
"typeVersion": 1
},
{
"id": "6c82769b-e784-4a38-b2ed-447da7f1a6f7",
"name": "Aggregate results in a single object",
"type": "n8n-nodes-base.aggregate",
"position": [
1760,
1080
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "c4fbad75-5811-4031-bdfe-ee494067ded3",
"connections": {
"Limit": {
"main": [
[
{
"node": "Get encoded news URL",
"type": "main",
"index": 0
}
]
]
},
"Decoded url": {
"main": [
[
{
"node": "Aggregate results in a single object",
"type": "main",
"index": 0
}
]
]
},
"Map needed keys": {
"main": [
[
{
"node": "Prepare decoding variables",
"type": "main",
"index": 0
}
]
]
},
"Call decoding URL": {
"main": [
[
{
"node": "Decoded url",
"type": "main",
"index": 0
}
]
]
},
"Get encoded news URL": {
"main": [
[
{
"node": "Extract decoding keys",
"type": "main",
"index": 0
}
]
]
},
"Extract decoding keys": {
"main": [
[
{
"node": "Map needed keys",
"type": "main",
"index": 0
}
]
]
},
"Reading Google News RSS": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
]
]
},
"Prepare decoding variables": {
"main": [
[
{
"node": "Call decoding URL",
"type": "main",
"index": 0
}
]
]
},
"When clicking Test workflow": {
"main": [
[
{
"node": "Reading Google News RSS",
"type": "main",
"index": 0
}
]
]
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,423 @@
{
"id": "TtoDcjgthgA4NTkU",
"meta": {
"instanceId": "fb261afc5089eae952e09babdadd9983000b3d863639802f6ded8c5be2e40067",
"templateCredsSetupCompleted": true
},
"name": "AI Voice Chat using Webhook, Memory Manager, OpenAI, Google Gemini & ElevenLabs",
"tags": [
{
"id": "mqOrNvCDgQLzPA2x",
"name": "Workflows",
"createdAt": "2024-08-07T14:18:53.614Z",
"updatedAt": "2024-08-07T14:18:53.614Z"
}
],
"nodes": [
{
"id": "86cbf150-df4f-42f7-b7b3-e03c32e6f23c",
"name": "Get Chat",
"type": "@n8n/n8n-nodes-langchain.memoryManager",
"position": [
1700,
-400
],
"parameters": {
"options": {}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "a9153a24-e902-4f29-9b83-447317ce3119",
"name": "Insert Chat",
"type": "@n8n/n8n-nodes-langchain.memoryManager",
"position": [
2540,
-400
],
"parameters": {
"mode": "insert",
"messages": {
"messageValues": [
{
"type": "user",
"message": "={{ $('OpenAI - Speech to Text').item.json[\"text\"] }}"
},
{
"type": "ai",
"message": "={{ $json.text }}"
}
]
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "f5c272d4-248b-45a5-87b5-eb659a865d05",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1664,
-491
],
"parameters": {
"color": 6,
"width": 486.4746124819703,
"height": 238.4911357933579,
"content": "## Get Context"
},
"typeVersion": 1
},
{
"id": "32ad17ca-0045-487d-9387-71c2e73629d4",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
2510,
-489
],
"parameters": {
"color": 6,
"width": 321.2536584847704,
"height": 231.05945912581728,
"content": "## Save Context"
},
"typeVersion": 1
},
{
"id": "17ae4f1a-6192-4c52-8157-3cb47b37e0fb",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
2020,
-400
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData",
"destinationFieldName": "context"
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "00b3081e-fbcd-489b-b45a-4e847c346594",
"name": "Window Buffer Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
2080,
-100
],
"parameters": {
"sessionKey": "test-0dacb3b5-4bcd-47dd-8456-dcfd8c258204",
"sessionIdType": "customKey"
},
"typeVersion": 1.2
},
{
"id": "55ca2790-e905-414a-a9f6-7d88a9e5807d",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
2220,
-100
],
"parameters": {
"options": {},
"modelName": "models/gemini-1.5-flash"
},
"credentials": {
"googlePalmApi": {
"id": "2bUF1ZI9hoMIM5XN",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "e8b3433f-b205-404c-9f05-504556d6b6dd",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3560,
-400
],
"parameters": {
"options": {},
"respondWith": "binary"
},
"typeVersion": 1.1
},
{
"id": "de296743-5ac7-454b-bf3a-d020cc024511",
"name": "ElevenLabs - Generate Audio",
"type": "n8n-nodes-base.httpRequest",
"position": [
3240,
-400
],
"parameters": {
"url": "=https://api.elevenlabs.io/v1/text-to-speech/{{voice id}}",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "text",
"value": "={{ $('Basic LLM Chain').item.json.text }}"
}
]
},
"genericAuthType": "httpCustomAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpCustomAuth": {
"id": "lnGfV4BlxSE6Xc4X",
"name": "Eleven Labs"
}
},
"typeVersion": 4.2
},
{
"id": "214e15f2-8a16-4598-b4ac-9fc2ec6545e6",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
3040,
-560
],
"parameters": {
"width": 468.73250812192407,
"height": 843.7602354099661,
"content": "* ### For the Text-to-Speech part, we'll use ElevenLabs.io, which is free and offers a variety of voices to choose from. However, you can also use the OpenAI `\"Generate audio\"` node instead.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n* ### Since there is no pre-built node for `\"ElevenLabs\"` in n8n, we'll connect to it through its API using the \"HTTP Request\" node.\n\n## Prerequisites:\n* ### `\"ElevenLabs API Key\"` (you can obtain it from their website).\n* ### `\"Voice ID\"` (you can also get it from ElevenLabs' \"Voice Library\").\n## Setup\n* ### In the URL parameter, replace \"{{voice id}}\" at the end of the URL with the Voice ID you obtained from ElevenLabs.io.\n* ### To set up your API Key, add custom authentication and include the following `JSON` with your acual ElevenLabs API Key:\n```json\n{\n \"headers\": {\n \"xi-api-key\": \"put-your-API-Key-here\"\n }\n}\n```"
},
"typeVersion": 1
},
{
"id": "94ad934c-4a13-47b1-83a5-76fab43b3a47",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1663,
-598
],
"parameters": {
"color": 6,
"width": 487.4293487597613,
"height": 91.01435855269375,
"content": "### The \"Get Chat,\" \"Insert Chat,\" and \"Window Buffer Memory\" nodes will help the LLM model maintain context throughout the conversation."
},
"typeVersion": 1
},
{
"id": "0a96f48d-0d8b-4240-9eab-a681bfd4c8b5",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
2900,
-400
],
"parameters": {},
"typeVersion": 1
},
{
"id": "9a5d4ddb-6403-4758-858e-9fbe10c421a9",
"name": "Basic LLM Chain",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
2200,
-400
],
"parameters": {
"text": "={{ $('OpenAI - Speech to Text').item.json[\"text\"] }}",
"messages": {
"messageValues": [
{
"type": "AIMessagePromptTemplate",
"message": "=To maintain context and fully understand the user's question, always review the previous conversation between you and him before providing an answer.\nThis is the previous conversation:\n{{ $('Aggregate').item.json[\"context\"].map(m => `\nHuman: ${m.human || 'undefined'}\nAI Assistant: ${m.ai || 'undefined'}\n`).join('') }}"
}
]
},
"promptType": "define"
},
"typeVersion": 1.4
},
{
"id": "f2f99895-9678-41b8-ad28-db40e1e23dc0",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
1320,
-400
],
"webhookId": "e9f611eb-a8dd-4520-8d24-9f36deaca528",
"parameters": {
"path": "voice_message",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "d9a5fb04-4c02-4da4-b690-7b0ecd0ae052",
"name": "OpenAI - Speech to Text",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1500,
-400
],
"parameters": {
"options": {},
"resource": "audio",
"operation": "transcribe",
"binaryPropertyName": "voice_message"
},
"credentials": {
"openAiApi": {
"id": "2Cije3KX7OIVwn9B",
"name": "n8n OpenAI"
}
},
"typeVersion": 1.3
}
],
"active": true,
"pinData": {},
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"executionOrder": "v1",
"saveManualExecutions": true
},
"versionId": "fe5792ca-03d7-4cdd-96db-20f4cd479c7e",
"connections": {
"Limit": {
"main": [
[
{
"node": "ElevenLabs - Generate Audio",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "OpenAI - Speech to Text",
"type": "main",
"index": 0
}
]
]
},
"Get Chat": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"Aggregate": {
"main": [
[
{
"node": "Basic LLM Chain",
"type": "main",
"index": 0
}
]
]
},
"Insert Chat": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
]
]
},
"Basic LLM Chain": {
"main": [
[
{
"node": "Insert Chat",
"type": "main",
"index": 0
}
]
]
},
"Window Buffer Memory": {
"ai_memory": [
[
{
"node": "Insert Chat",
"type": "ai_memory",
"index": 0
},
{
"node": "Get Chat",
"type": "ai_memory",
"index": 0
}
]
]
},
"OpenAI - Speech to Text": {
"main": [
[
{
"node": "Get Chat",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Basic LLM Chain",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"ElevenLabs - Generate Audio": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
}
}
}

View File

@@ -0,0 +1,423 @@
{
"id": "TtoDcjgthgA4NTkU",
"meta": {
"instanceId": "fb261afc5089eae952e09babdadd9983000b3d863639802f6ded8c5be2e40067",
"templateCredsSetupCompleted": true
},
"name": "AI Voice Chat using Webhook, Memory Manager, OpenAI, Google Gemini & ElevenLabs",
"tags": [
{
"id": "mqOrNvCDgQLzPA2x",
"name": "Workflows",
"createdAt": "2024-08-07T14:18:53.614Z",
"updatedAt": "2024-08-07T14:18:53.614Z"
}
],
"nodes": [
{
"id": "86cbf150-df4f-42f7-b7b3-e03c32e6f23c",
"name": "Get Chat",
"type": "@n8n/n8n-nodes-langchain.memoryManager",
"position": [
1700,
-400
],
"parameters": {
"options": {}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "a9153a24-e902-4f29-9b83-447317ce3119",
"name": "Insert Chat",
"type": "@n8n/n8n-nodes-langchain.memoryManager",
"position": [
2540,
-400
],
"parameters": {
"mode": "insert",
"messages": {
"messageValues": [
{
"type": "user",
"message": "={{ $('OpenAI - Speech to Text').item.json[\"text\"] }}"
},
{
"type": "ai",
"message": "={{ $json.text }}"
}
]
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "f5c272d4-248b-45a5-87b5-eb659a865d05",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1664,
-491
],
"parameters": {
"color": 6,
"width": 486.4746124819703,
"height": 238.4911357933579,
"content": "## Get Context"
},
"typeVersion": 1
},
{
"id": "32ad17ca-0045-487d-9387-71c2e73629d4",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
2510,
-489
],
"parameters": {
"color": 6,
"width": 321.2536584847704,
"height": 231.05945912581728,
"content": "## Save Context"
},
"typeVersion": 1
},
{
"id": "17ae4f1a-6192-4c52-8157-3cb47b37e0fb",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
2020,
-400
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData",
"destinationFieldName": "context"
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "00b3081e-fbcd-489b-b45a-4e847c346594",
"name": "Window Buffer Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
2080,
-100
],
"parameters": {
"sessionKey": "test-0dacb3b5-4bcd-47dd-8456-dcfd8c258204",
"sessionIdType": "customKey"
},
"typeVersion": 1.2
},
{
"id": "55ca2790-e905-414a-a9f6-7d88a9e5807d",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
2220,
-100
],
"parameters": {
"options": {},
"modelName": "models/gemini-1.5-flash"
},
"credentials": {
"googlePalmApi": {
"id": "2bUF1ZI9hoMIM5XN",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "e8b3433f-b205-404c-9f05-504556d6b6dd",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3560,
-400
],
"parameters": {
"options": {},
"respondWith": "binary"
},
"typeVersion": 1.1
},
{
"id": "de296743-5ac7-454b-bf3a-d020cc024511",
"name": "ElevenLabs - Generate Audio",
"type": "n8n-nodes-base.httpRequest",
"position": [
3240,
-400
],
"parameters": {
"url": "=https://api.elevenlabs.io/v1/text-to-speech/{{voice id}}",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "text",
"value": "={{ $('Basic LLM Chain').item.json.text }}"
}
]
},
"genericAuthType": "httpCustomAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpCustomAuth": {
"id": "lnGfV4BlxSE6Xc4X",
"name": "Eleven Labs"
}
},
"typeVersion": 4.2
},
{
"id": "214e15f2-8a16-4598-b4ac-9fc2ec6545e6",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
3040,
-560
],
"parameters": {
"width": 468.73250812192407,
"height": 843.7602354099661,
"content": "* ### For the Text-to-Speech part, we'll use ElevenLabs.io, which is free and offers a variety of voices to choose from. However, you can also use the OpenAI `\"Generate audio\"` node instead.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n* ### Since there is no pre-built node for `\"ElevenLabs\"` in n8n, we'll connect to it through its API using the \"HTTP Request\" node.\n\n## Prerequisites:\n* ### `\"ElevenLabs API Key\"` (you can obtain it from their website).\n* ### `\"Voice ID\"` (you can also get it from ElevenLabs' \"Voice Library\").\n## Setup\n* ### In the URL parameter, replace \"{{voice id}}\" at the end of the URL with the Voice ID you obtained from ElevenLabs.io.\n* ### To set up your API Key, add custom authentication and include the following `JSON` with your acual ElevenLabs API Key:\n```json\n{\n \"headers\": {\n \"xi-api-key\": \"put-your-API-Key-here\"\n }\n}\n```"
},
"typeVersion": 1
},
{
"id": "94ad934c-4a13-47b1-83a5-76fab43b3a47",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1663,
-598
],
"parameters": {
"color": 6,
"width": 487.4293487597613,
"height": 91.01435855269375,
"content": "### The \"Get Chat,\" \"Insert Chat,\" and \"Window Buffer Memory\" nodes will help the LLM model maintain context throughout the conversation."
},
"typeVersion": 1
},
{
"id": "0a96f48d-0d8b-4240-9eab-a681bfd4c8b5",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
2900,
-400
],
"parameters": {},
"typeVersion": 1
},
{
"id": "9a5d4ddb-6403-4758-858e-9fbe10c421a9",
"name": "Basic LLM Chain",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
2200,
-400
],
"parameters": {
"text": "={{ $('OpenAI - Speech to Text').item.json[\"text\"] }}",
"messages": {
"messageValues": [
{
"type": "AIMessagePromptTemplate",
"message": "=To maintain context and fully understand the user's question, always review the previous conversation between you and him before providing an answer.\nThis is the previous conversation:\n{{ $('Aggregate').item.json[\"context\"].map(m => `\nHuman: ${m.human || 'undefined'}\nAI Assistant: ${m.ai || 'undefined'}\n`).join('') }}"
}
]
},
"promptType": "define"
},
"typeVersion": 1.4
},
{
"id": "f2f99895-9678-41b8-ad28-db40e1e23dc0",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
1320,
-400
],
"webhookId": "e9f611eb-a8dd-4520-8d24-9f36deaca528",
"parameters": {
"path": "voice_message",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "d9a5fb04-4c02-4da4-b690-7b0ecd0ae052",
"name": "OpenAI - Speech to Text",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1500,
-400
],
"parameters": {
"options": {},
"resource": "audio",
"operation": "transcribe",
"binaryPropertyName": "voice_message"
},
"credentials": {
"openAiApi": {
"id": "2Cije3KX7OIVwn9B",
"name": "n8n OpenAI"
}
},
"typeVersion": 1.3
}
],
"active": true,
"pinData": {},
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"executionOrder": "v1",
"saveManualExecutions": true
},
"versionId": "fe5792ca-03d7-4cdd-96db-20f4cd479c7e",
"connections": {
"Limit": {
"main": [
[
{
"node": "ElevenLabs - Generate Audio",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "OpenAI - Speech to Text",
"type": "main",
"index": 0
}
]
]
},
"Get Chat": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"Aggregate": {
"main": [
[
{
"node": "Basic LLM Chain",
"type": "main",
"index": 0
}
]
]
},
"Insert Chat": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
]
]
},
"Basic LLM Chain": {
"main": [
[
{
"node": "Insert Chat",
"type": "main",
"index": 0
}
]
]
},
"Window Buffer Memory": {
"ai_memory": [
[
{
"node": "Insert Chat",
"type": "ai_memory",
"index": 0
},
{
"node": "Get Chat",
"type": "ai_memory",
"index": 0
}
]
]
},
"OpenAI - Speech to Text": {
"main": [
[
{
"node": "Get Chat",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Basic LLM Chain",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"ElevenLabs - Generate Audio": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
}
}
}

View File

@@ -0,0 +1,594 @@
{
"nodes": [
{
"id": "a99b3164-fe36-4dde-9525-110c1ae08afb",
"name": "Convert raw to base64",
"type": "n8n-nodes-base.code",
"position": [
3320,
580
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const encoded = Buffer.from($json.raw).toString('base64');\n\nreturn { encoded };"
},
"typeVersion": 2
},
{
"id": "f0f731bd-7b2f-4c39-bc06-42fd57bc4ae8",
"name": "Add email draft to thread",
"type": "n8n-nodes-base.httpRequest",
"position": [
3580,
580
],
"parameters": {
"url": "https://www.googleapis.com/gmail/v1/users/me/drafts",
"method": "POST",
"options": {},
"jsonBody": "={\"message\":{\"raw\":\"{{ $json.encoded }}\", \"threadId\": \"{{ $('Map fields for further processing').item.json[\"threadId\"] }}\"}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "gmailOAuth2"
},
"credentials": {
"gmailOAuth2": {
"id": "uBcIMfsTtKjexw7I",
"name": "Gmail (workfloowstutorial@gmail.com)"
}
},
"typeVersion": 4.1
},
{
"id": "c1ce3400-4582-46c7-a85d-8fa9c325ff7b",
"name": "Remove AI label from email",
"type": "n8n-nodes-base.gmail",
"position": [
3820,
580
],
"parameters": {
"resource": "thread",
"threadId": "={{ $('Map fields for further processing').item.json[\"threadId\"] }}",
"operation": "removeLabels"
},
"credentials": {
"gmailOAuth2": {
"id": "uBcIMfsTtKjexw7I",
"name": "Gmail (workfloowstutorial@gmail.com)"
}
},
"typeVersion": 2.1
},
{
"id": "65f0508a-ca2e-49ce-b02f-ef6505b5e983",
"name": "Schedule trigger (1 min)",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
960,
580
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 1
}
]
}
},
"typeVersion": 1.1
},
{
"id": "ca4a209b-a79d-4911-b69b-1db22808be60",
"name": "Map fields for further processing",
"type": "n8n-nodes-base.set",
"position": [
2620,
580
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a77b2d79-1e70-410c-a657-f3d618154ea1",
"name": "response",
"type": "string",
"value": "={{ $json.output }}"
},
{
"id": "20850cac-f82c-4f02-84f0-3de31871a5b8",
"name": "threadId",
"type": "string",
"value": "={{ $('Get single message content').item.json[\"threadId\"] }}"
},
{
"id": "d270c18e-39a0-4d87-85f0-cc1ffc9c10ff",
"name": "to",
"type": "string",
"value": "={{ $('Get single message content').item.json[\"from\"][\"text\"] }}"
},
{
"id": "30acb50b-bdde-44bf-803c-76e0ae65f526",
"name": "subject",
"type": "string",
"value": "={{ $('Get single message content').item.json[\"subject\"] }}"
},
{
"id": "88914536-8c25-4877-8914-feab5e32fae3",
"name": "messageId",
"type": "string",
"value": "={{ $('Get threads with specific labels').item.json[\"id\"] }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "93eb3844-f1fe-4b09-bcae-3e372a19ab6f",
"name": "Convert response to HTML",
"type": "n8n-nodes-base.markdown",
"position": [
2860,
580
],
"parameters": {
"mode": "markdownToHtml",
"options": {
"simpleLineBreaks": false
},
"markdown": "={{ $json.response }}",
"destinationKey": "response"
},
"typeVersion": 1
},
{
"id": "da35eda9-b63e-49f9-8fe8-7517c1445c92",
"name": "Build email raw",
"type": "n8n-nodes-base.set",
"position": [
3100,
580
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "913e9cb1-10de-4637-bf48-40272c7c7fe3",
"name": "raw",
"type": "string",
"value": "=To: {{ $json.to }}\nSubject: {{ $json.subject }}\nContent-Type: text/html; charset=\"utf-8\"\n\n{{ $json.response }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "b667a399-a178-42e3-a587-4eccd2a153d8",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
460,
460
],
"parameters": {
"color": 4,
"width": 420.4803040774015,
"height": 189.69151356225348,
"content": "## Reply draft with OpenAI Assistant\nThis workflow automatically transfers content of incoming email messages with specific labels into OpenAI Assitant and returns reply draft. After draft is composed, trigger label is deleted from the thread.\n\n**Please remember to configure your OpenAI Assistant first.**"
},
"typeVersion": 1
},
{
"id": "fe47636b-2142-4c40-a937-2ec360b230ae",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
900,
460
],
"parameters": {
"width": 451.41125086385614,
"height": 313.3056033573073,
"content": "### Schedule trigger and get emails\nRun the workflow in equal intervals and check for threads with specific labels (trigger labels)."
},
"typeVersion": 1
},
{
"id": "c9bfa42c-a045-404d-aebe-d87dceb68f1a",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
460,
680
],
"parameters": {
"color": 3,
"width": 421.0932411886662,
"height": 257.42916378714597,
"content": "## \u26a0\ufe0f Note\n\n1. Complete video guide for this workflow is available [on my YouTube](https://youtu.be/a8Dhj3Zh9vQ). \n2. Remember to add your credentials and configure nodes (covered in the video guide).\n3. If you like this workflow, please subscribe to [my YouTube channel](https://www.youtube.com/@workfloows) and/or [my newsletter](https://workfloows.com/).\n\n**Thank you for your support!**"
},
"typeVersion": 1
},
{
"id": "40424340-c0ec-435a-9ce0-0e0dc3b94cfc",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2160,
460
],
"parameters": {
"width": 381.6458068293894,
"height": 313.7892229150129,
"content": "### Generate reply\nTransfer email content to OpenAI Assitant and return AI-generated reply.\n"
},
"typeVersion": 1
},
{
"id": "e7cce507-6658-414d-8cbc-3af847dad124",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2800,
460
],
"parameters": {
"width": 219.88389496558554,
"height": 314.75072291501283,
"content": "### Create HTML message\nConvert incoming Markdown from OpenAI Assistant into HTML content."
},
"typeVersion": 1
},
{
"id": "2b383967-0a23-46a1-9a19-a9532a3c3425",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
3040,
460
],
"parameters": {
"width": 461.3148409669012,
"height": 314.75072291501283,
"content": "### Build and encode message\nCreate raw message in RFC standard and encode it into base64 string (please see [Gmail API reference](https://developers.google.com/gmail/api/reference/rest/v1/users.drafts/create) for more details)."
},
"typeVersion": 1
},
{
"id": "07685b17-cf22-4adf-a6b7-7acc2d863115",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
3520,
460
],
"parameters": {
"width": 219.88389496558554,
"height": 314.75072291501283,
"content": "### Insert reply draft\nAdd reply draft from OpenAI Assistant to specific Gmail thread."
},
"typeVersion": 1
},
{
"id": "1e8109f8-7dd3-4308-a5e8-32382aa41805",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
3760,
460
],
"parameters": {
"width": 219.88389496558554,
"height": 314.75072291501283,
"content": "### Remove label\nDelete trigger label from the Gmail thread."
},
"typeVersion": 1
},
{
"id": "d488db90-7367-49fa-b366-ccdfc796b5b3",
"name": "Get threads with specific labels",
"type": "n8n-nodes-base.gmail",
"position": [
1180,
580
],
"parameters": {
"filters": {
"labelIds": []
},
"resource": "thread",
"returnAll": true
},
"credentials": {
"gmailOAuth2": {
"id": "uBcIMfsTtKjexw7I",
"name": "Gmail (workfloowstutorial@gmail.com)"
}
},
"typeVersion": 2.1
},
{
"id": "9f5262c5-d319-4a9d-af6e-aa42970d1a6f",
"name": "Ask OpenAI Assistant",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
2220,
580
],
"parameters": {
"text": "={{ $json.text }}",
"prompt": "define",
"options": {},
"resource": "assistant",
"assistantId": {
"__rl": true,
"mode": "list",
"value": "asst_kmKeAtwF2rv0vgF0ujY4jlp6",
"cachedResultName": "Customer assistant"
}
},
"credentials": {
"openAiApi": {
"id": "jazew1WAaSRrjcHp",
"name": "OpenAI (workfloows@gmail.com)"
}
},
"typeVersion": 1
},
{
"id": "6ffd7d66-40b6-49a4-9e15-9742bda73d2f",
"name": "Loop over threads",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1440,
580
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "8afc47c8-075f-4f3d-a89d-fda81fc270fc",
"name": "Get thread messages",
"type": "n8n-nodes-base.gmail",
"position": [
1700,
820
],
"parameters": {
"options": {
"returnOnlyMessages": true
},
"resource": "thread",
"threadId": "={{ $json.id }}",
"operation": "get"
},
"credentials": {
"gmailOAuth2": {
"id": "uBcIMfsTtKjexw7I",
"name": "Gmail (workfloowstutorial@gmail.com)"
}
},
"typeVersion": 2.1
},
{
"id": "2286bfa7-dcb8-4a61-a71b-ea58e21bf7ab",
"name": "Return last message in thread",
"type": "n8n-nodes-base.limit",
"position": [
1920,
820
],
"parameters": {
"keep": "lastItems"
},
"typeVersion": 1
},
{
"id": "44c52e61-dd88-4499-85db-69ce4704c2b2",
"name": "Get single message content",
"type": "n8n-nodes-base.gmail",
"position": [
1700,
460
],
"parameters": {
"simple": false,
"options": {},
"messageId": "={{ $json.id }}",
"operation": "get"
},
"credentials": {
"gmailOAuth2": {
"id": "uBcIMfsTtKjexw7I",
"name": "Gmail (workfloowstutorial@gmail.com)"
}
},
"typeVersion": 2.1
},
{
"id": "7ca62611-f02e-47bf-b940-3a56ece443b7",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1640,
340
],
"parameters": {
"width": 219.88389496558554,
"height": 314.75072291501283,
"content": "### Return message content\nRetrieve content of the last message in the thread."
},
"typeVersion": 1
},
{
"id": "165df2a4-3c94-456d-9906-be8020098802",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
1640,
680
],
"parameters": {
"width": 470.88389496558545,
"height": 314.75072291501283,
"content": "### Get last message from thread\nReturn all messages for a single thread and pass for further processing only the last one."
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"connections": {
"Build email raw": {
"main": [
[
{
"node": "Convert raw to base64",
"type": "main",
"index": 0
}
]
]
},
"Loop over threads": {
"main": [
[
{
"node": "Get single message content",
"type": "main",
"index": 0
}
],
[
{
"node": "Get thread messages",
"type": "main",
"index": 0
}
]
]
},
"Get thread messages": {
"main": [
[
{
"node": "Return last message in thread",
"type": "main",
"index": 0
}
]
]
},
"Ask OpenAI Assistant": {
"main": [
[
{
"node": "Map fields for further processing",
"type": "main",
"index": 0
}
]
]
},
"Convert raw to base64": {
"main": [
[
{
"node": "Add email draft to thread",
"type": "main",
"index": 0
}
]
]
},
"Convert response to HTML": {
"main": [
[
{
"node": "Build email raw",
"type": "main",
"index": 0
}
]
]
},
"Schedule trigger (1 min)": {
"main": [
[
{
"node": "Get threads with specific labels",
"type": "main",
"index": 0
}
]
]
},
"Add email draft to thread": {
"main": [
[
{
"node": "Remove AI label from email",
"type": "main",
"index": 0
}
]
]
},
"Get single message content": {
"main": [
[
{
"node": "Ask OpenAI Assistant",
"type": "main",
"index": 0
}
]
]
},
"Return last message in thread": {
"main": [
[
{
"node": "Loop over threads",
"type": "main",
"index": 0
}
]
]
},
"Get threads with specific labels": {
"main": [
[
{
"node": "Loop over threads",
"type": "main",
"index": 0
}
]
]
},
"Map fields for further processing": {
"main": [
[
{
"node": "Convert response to HTML",
"type": "main",
"index": 0
}
]
]
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,839 @@
{
"id": "JxFP8FJ2W7e4Kmqn",
"meta": {
"instanceId": "fb8bc2e315f7f03c97140b30aa454a27bc7883a19000fa1da6e6b571bf56ad6d",
"templateCredsSetupCompleted": true
},
"name": "RAG on living data",
"tags": [],
"nodes": [
{
"id": "49086cdf-a38c-4cb8-9be9-d3e6ea5bdde5",
"name": "Embeddings OpenAI",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
1740,
1040
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "X7Jf0zECd3IkQdSw",
"name": "OpenAi (octionicsolutions)"
}
},
"typeVersion": 1
},
{
"id": "f0670721-92f4-422a-99c9-f9c2aa6fe21f",
"name": "Token Splitter",
"type": "@n8n/n8n-nodes-langchain.textSplitterTokenSplitter",
"position": [
2380,
540
],
"parameters": {
"chunkSize": 500
},
"typeVersion": 1
},
{
"id": "fe80ecac-4f79-4b07-ad8e-60ab5f980cba",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1180,
-200
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "81b79248-08e8-4214-872b-1796e51ad0a4",
"name": "Question and Answer Chain",
"type": "@n8n/n8n-nodes-langchain.chainRetrievalQa",
"position": [
744,
495
],
"parameters": {
"options": {}
},
"typeVersion": 1.3
},
{
"id": "e78f7b63-baef-4834-8f1b-aecfa9102d6c",
"name": "Vector Store Retriever",
"type": "@n8n/n8n-nodes-langchain.retrieverVectorStore",
"position": [
844,
715
],
"parameters": {},
"typeVersion": 1
},
{
"id": "1d5ffbd0-b2cf-4660-a291-581d18608ecd",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
704,
715
],
"parameters": {
"model": "gpt-4o",
"options": {}
},
"credentials": {
"openAiApi": {
"id": "X7Jf0zECd3IkQdSw",
"name": "OpenAi (octionicsolutions)"
}
},
"typeVersion": 1
},
{
"id": "37a3063f-aa21-4347-a72f-6dd316c58366",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
524,
495
],
"webhookId": "74479a54-418f-4de2-b70d-cfb3e3fdd5a7",
"parameters": {
"public": true,
"options": {}
},
"typeVersion": 1.1
},
{
"id": "5924bc01-1694-4b5c-8a06-7c46ee4c6425",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
520,
-200
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 1
}
]
}
},
"typeVersion": 1.2
},
{
"id": "5067eda6-8bbe-407a-a6af-93e81be53661",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
620,
0
],
"parameters": {
"width": 329.16412916774584,
"height": 312.52803480051045,
"content": "## Switch trigger (optional)\nIf you are on the cloud plan, consider switching to the Notion Trigger Node instead, to save on executions."
},
"typeVersion": 1
},
{
"id": "33458828-484d-426b-a3d1-974a81c6162e",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
1620,
-60
],
"parameters": {},
"typeVersion": 1
},
{
"id": "4d39503a-378e-4942-a5d4-8c62785aac44",
"name": "Limit1",
"type": "n8n-nodes-base.limit",
"position": [
2660,
-60
],
"parameters": {},
"typeVersion": 1
},
{
"id": "0e0b1391-3fe5-4d80-a2eb-a2483b79d9a6",
"name": "Delete old embeddings if exist",
"type": "n8n-nodes-base.supabase",
"position": [
1400,
-60
],
"parameters": {
"tableId": "documents",
"operation": "delete",
"filterType": "string",
"filterString": "=metadata->>id=eq.{{ $('Input Reference').item.json.id }}"
},
"credentials": {
"supabaseApi": {
"id": "DjIb4HMTYXhTU8Uc",
"name": "Supabase (VectorStore)"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "4a8614e4-0a53-4731-bc68-57505d7d0a09",
"name": "Get page blocks",
"type": "n8n-nodes-base.notion",
"position": [
1840,
-60
],
"parameters": {
"blockId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Input Reference').item.json.id }}"
},
"resource": "block",
"operation": "getAll",
"returnAll": true,
"fetchNestedBlocks": true
},
"credentials": {
"notionApi": {
"id": "ObmaBA0dJss3JJPv",
"name": "Notion (octionicsolutions / Test)"
}
},
"executeOnce": true,
"typeVersion": 2.2
},
{
"id": "8c922895-49d6-4778-8356-6f6cf49e5420",
"name": "Default Data Loader",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
2300,
260
],
"parameters": {
"options": {
"metadata": {
"metadataValues": [
{
"name": "id",
"value": "={{ $('Input Reference').item.json.id }}"
},
{
"name": "name",
"value": "={{ $('Input Reference').item.json.name }}"
}
]
}
}
},
"typeVersion": 1
},
{
"id": "8ad7ff2e-4bc2-4821-ae03-bab2dc11d947",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
2220,
400
],
"parameters": {
"width": 376.2098538932132,
"height": 264.37628764336097,
"content": "## Adjust chunk size and overlap\nFor more accurate search results, increase the overlap. For the *text-embedding-ada-002* model the chunk size plus overlap must not exceed 8191"
},
"typeVersion": 1
},
{
"id": "8078d59a-f45f-4e96-a8ec-6c2f1c328e84",
"name": "Input Reference",
"type": "n8n-nodes-base.noOp",
"position": [
960,
-200
],
"parameters": {},
"typeVersion": 1
},
{
"id": "aae6c517-a316-40e3-aee9-1cc4b448689f",
"name": "Notion Trigger",
"type": "n8n-nodes-base.notionTrigger",
"disabled": true,
"position": [
740,
120
],
"parameters": {
"event": "pagedUpdatedInDatabase",
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"databaseId": {
"__rl": true,
"mode": "list",
"value": "ec6dc7b4-9ce0-47f7-8025-ef09295999fd",
"cachedResultUrl": "https://www.notion.so/ec6dc7b49ce047f78025ef09295999fd",
"cachedResultName": "Knowledge Base"
}
},
"credentials": {
"notionApi": {
"id": "ObmaBA0dJss3JJPv",
"name": "Notion (octionicsolutions / Test)"
}
},
"typeVersion": 1
},
{
"id": "3a43d66d-d4e3-4ca1-aee9-85ac65160e45",
"name": "Get updated pages",
"type": "n8n-nodes-base.notion",
"position": [
740,
-200
],
"parameters": {
"filters": {
"conditions": [
{
"key": "Last edited time|last_edited_time",
"condition": "equals",
"lastEditedTime": "={{ $now.minus(1, 'minutes').toISO() }}"
}
]
},
"options": {},
"resource": "databasePage",
"operation": "getAll",
"databaseId": {
"__rl": true,
"mode": "list",
"value": "ec6dc7b4-9ce0-47f7-8025-ef09295999fd",
"cachedResultUrl": "https://www.notion.so/ec6dc7b49ce047f78025ef09295999fd",
"cachedResultName": "Knowledge Base"
},
"filterType": "manual"
},
"credentials": {
"notionApi": {
"id": "ObmaBA0dJss3JJPv",
"name": "Notion (octionicsolutions / Test)"
}
},
"typeVersion": 2.2
},
{
"id": "bbf1296f-4e2b-4a38-bdf3-ae2b63cc7774",
"name": "Sticky Note23",
"type": "n8n-nodes-base.stickyNote",
"position": [
900,
-300
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "This placeholder serves as a reference point so it is easier to swap the data source with a different service"
},
"typeVersion": 1
},
{
"id": "631e1e10-0b52-4a17-89a4-769ac563321f",
"name": "Sticky Note24",
"type": "n8n-nodes-base.stickyNote",
"position": [
1340,
-160
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "All chunks of a previous version of the document are being deleted by filtering the meta data by the given ID"
},
"typeVersion": 1
},
{
"id": "6c830c83-4b70-4719-8e2a-26846e60085c",
"name": "Sticky Note25",
"type": "n8n-nodes-base.stickyNote",
"position": [
1560,
-160
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Reduce the active streams/items to just 1 to prevent the following nodes from double-processing"
},
"typeVersion": 1
},
{
"id": "46c8e4e4-0a5e-4ede-947b-5773710d4e55",
"name": "Sticky Note26",
"type": "n8n-nodes-base.stickyNote",
"position": [
1780,
-160
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Retrieve all page contents/blocks"
},
"typeVersion": 1
},
{
"id": "0369e610-d074-4812-9d04-8615b42965a5",
"name": "Sticky Note27",
"type": "n8n-nodes-base.stickyNote",
"position": [
2600,
-160
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Reduce the active streams/items to just 1 to prevent the following nodes from double-processing"
},
"typeVersion": 1
},
{
"id": "4f3bce54-1650-45fa-abb0-c881358c7e8d",
"name": "Sticky Note28",
"type": "n8n-nodes-base.stickyNote",
"position": [
2220,
-160
],
"parameters": {
"color": 7,
"width": 375.9283286479995,
"height": 275.841854198618,
"content": "Embed item and store in Vector Store. Depending on the length the content is being split up into multiple chunks/embeds"
},
"typeVersion": 1
},
{
"id": "44125921-e068-4a5d-a56b-b0e63c103556",
"name": "Supabase Vector Store1",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
924,
935
],
"parameters": {
"options": {},
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
}
},
"credentials": {
"supabaseApi": {
"id": "DjIb4HMTYXhTU8Uc",
"name": "Supabase (VectorStore)"
}
},
"typeVersion": 1
},
{
"id": "467322a9-949d-4569-aac6-92196da46ba5",
"name": "Sticky Note30",
"type": "n8n-nodes-base.stickyNote",
"position": [
460,
400
],
"parameters": {
"color": 7,
"width": 730.7522093855692,
"height": 668.724737081502,
"content": "Simple chat bot to ask specific questions while having access to the context of the Notion Knowledge Base which was stored in the Vector Store"
},
"typeVersion": 1
},
{
"id": "27f078cf-b309-4dd1-a8ce-b4fc504d6e29",
"name": "Sticky Note31",
"type": "n8n-nodes-base.stickyNote",
"position": [
1660,
900
],
"parameters": {
"color": 7,
"width": 219.31927574471658,
"height": 275.841854198618,
"content": "Model used for both creating and reading embeddings"
},
"typeVersion": 1
},
{
"id": "2f59cba1-4318-47e7-bf0b-b908d4186b86",
"name": "Supabase Vector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
2280,
-60
],
"parameters": {
"mode": "insert",
"options": {},
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
}
},
"credentials": {
"supabaseApi": {
"id": "DjIb4HMTYXhTU8Uc",
"name": "Supabase (VectorStore)"
}
},
"typeVersion": 1
},
{
"id": "729849e7-0eff-40c2-ae00-ae660c1eec69",
"name": "Sticky Note32",
"type": "n8n-nodes-base.stickyNote",
"position": [
1120,
-300
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Process each page/document separately."
},
"typeVersion": 1
},
{
"id": "3f632a24-ca0a-45c4-801d-041aa3f887a7",
"name": "Sticky Note29",
"type": "n8n-nodes-base.stickyNote",
"position": [
2220,
120
],
"parameters": {
"color": 7,
"width": 376.0759088111347,
"height": 275.841854198618,
"content": "Store additional meta data with each embed, especially the Notion ID, which can be later used to find all belonging entries of one page, even if they got split into multiple embeds."
},
"typeVersion": 1
},
{
"id": "ffaf3861-5287-4f57-8372-09216a18cb4d",
"name": "Sticky Note33",
"type": "n8n-nodes-base.stickyNote",
"position": [
460,
-300
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Using a manual approach for polling data from Notion for more accuracy."
},
"typeVersion": 1
},
{
"id": "cbbedfc0-4d64-42a6-8f55-21e04887305f",
"name": "Sticky Note34",
"type": "n8n-nodes-base.stickyNote",
"position": [
680,
-300
],
"parameters": {
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "## Select Database\nChoose the database which represents your Knowledge Base"
},
"typeVersion": 1
},
{
"id": "8b6767f2-1bc9-42fb-b319-f39f6734b9f2",
"name": "Sticky Note35",
"type": "n8n-nodes-base.stickyNote",
"position": [
2000,
-160
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Combine all contents to a single text formatted into one line which can be easily stored as an embed"
},
"typeVersion": 1
},
{
"id": "cdff1756-77d7-421e-8672-25c9862840b0",
"name": "Concatenate to single string",
"type": "n8n-nodes-base.summarize",
"position": [
2060,
-60
],
"parameters": {
"options": {},
"fieldsToSummarize": {
"values": [
{
"field": "content",
"separateBy": "\n",
"aggregation": "concatenate"
}
]
}
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "51075175-868a-4a3a-9580-5ad55e25ac71",
"connections": {
"Limit": {
"main": [
[
{
"node": "Get page blocks",
"type": "main",
"index": 0
}
]
]
},
"Limit1": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Notion Trigger": {
"main": [
[
{
"node": "Input Reference",
"type": "main",
"index": 0
}
]
]
},
"Token Splitter": {
"ai_textSplitter": [
[
{
"node": "Default Data Loader",
"type": "ai_textSplitter",
"index": 0
}
]
]
},
"Get page blocks": {
"main": [
[
{
"node": "Concatenate to single string",
"type": "main",
"index": 0
}
]
]
},
"Input Reference": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Delete old embeddings if exist",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get updated pages",
"type": "main",
"index": 0
}
]
]
},
"Embeddings OpenAI": {
"ai_embedding": [
[
{
"node": "Supabase Vector Store",
"type": "ai_embedding",
"index": 0
},
{
"node": "Supabase Vector Store1",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Get updated pages": {
"main": [
[
{
"node": "Input Reference",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Question and Answer Chain",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Default Data Loader": {
"ai_document": [
[
{
"node": "Supabase Vector Store",
"type": "ai_document",
"index": 0
}
]
]
},
"Supabase Vector Store": {
"main": [
[
{
"node": "Limit1",
"type": "main",
"index": 0
}
]
]
},
"Supabase Vector Store1": {
"ai_vectorStore": [
[
{
"node": "Vector Store Retriever",
"type": "ai_vectorStore",
"index": 0
}
]
]
},
"Vector Store Retriever": {
"ai_retriever": [
[
{
"node": "Question and Answer Chain",
"type": "ai_retriever",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "Question and Answer Chain",
"type": "main",
"index": 0
}
]
]
},
"Concatenate to single string": {
"main": [
[
{
"node": "Supabase Vector Store",
"type": "main",
"index": 0
}
]
]
},
"Delete old embeddings if exist": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
]
]
}
}
}

View File

@@ -0,0 +1,920 @@
{
"id": "w434EiZ2z7klQAyp",
"meta": {
"instanceId": "a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462",
"templateCredsSetupCompleted": true
},
"name": "Scrape Trustpilot Reviews with DeepSeek, Analyze Sentiment with OpenAI",
"tags": [
{
"id": "2VG6RbmUdJ2VZbrj",
"name": "Google Drive",
"createdAt": "2024-12-04T16:50:56.177Z",
"updatedAt": "2024-12-04T16:50:56.177Z"
},
{
"id": "paTcf5QZDJsC2vKY",
"name": "OpenAI",
"createdAt": "2024-12-04T16:52:10.768Z",
"updatedAt": "2024-12-04T16:52:10.768Z"
}
],
"nodes": [
{
"id": "095a8e10-1630-4a1a-b6c9-7950ae1ed803",
"name": "Split Out",
"type": "n8n-nodes-base.splitOut",
"position": [
320,
-380
],
"parameters": {
"options": {},
"fieldToSplitOut": "recensioni"
},
"typeVersion": 1
},
{
"id": "6ff4dd9d-eedd-4d84-b13a-b3c0db717409",
"name": "Information Extractor",
"type": "@n8n/n8n-nodes-langchain.informationExtractor",
"position": [
-440,
140
],
"parameters": {
"text": "=You need to extract the review from the following HTML: {{ $json.recensione }}",
"options": {
"systemPromptTemplate": "You are a review expert. You need to extract only the required information and report it without changing anything.\nAll the required information is in the text."
},
"attributes": {
"attributes": [
{
"name": "autore",
"required": true,
"description": "Extract the name of the review author"
},
{
"name": "valutazione",
"type": "number",
"required": true,
"description": "Extract the rating given to the review (from 1 to 5)"
},
{
"name": "data",
"required": true,
"description": "Extract review date in YYYY-MM-DD format"
},
{
"name": "titolo",
"required": true,
"description": "Extract the review title"
},
{
"name": "testo",
"required": true,
"description": "Extract the review text"
},
{
"name": "n_recensioni",
"type": "number",
"required": true,
"description": "Extract the total number of reviews made by the user"
},
{
"name": "nazione",
"required": true,
"description": "Extract the country of the user who wrote the review. Must be two characters"
}
]
}
},
"typeVersion": 1
},
{
"id": "0036f3b1-4832-4a35-8694-0893475a4119",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
60,
-100
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "ab666549-4eec-40e2-a702-0575c094a2d4",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json.Valutazione }}",
"rightValue": "={{ $('Split Out').item.json.recensioni.replace('/reviews/','') }}"
}
]
},
"looseTypeValidation": true
},
"executeOnce": false,
"typeVersion": 2.2
},
{
"id": "5423b55d-eb6c-41c6-9b26-410e3c92b85d",
"name": "When clicking \u2018Test workflow\u2019",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-700,
-380
],
"parameters": {},
"typeVersion": 1
},
{
"id": "506cdaa1-e0ba-4f29-b137-69d321b13c94",
"name": "Limit1",
"type": "n8n-nodes-base.limit",
"position": [
540,
-380
],
"parameters": {
"maxItems": 3
},
"typeVersion": 1
},
{
"id": "40f1e30d-8aed-4995-b4e4-2239248bd6e7",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-460,
-480
],
"parameters": {
"width": 212.25249169435213,
"height": 245.55481727574733,
"content": "Change to the name of the company registered on Trustpilot and the maximum number of pages to scrape"
},
"typeVersion": 1
},
{
"id": "e6d2fec1-7255-4270-86b4-6d6f39f44ccb",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-460,
80
],
"parameters": {
"width": 381,
"height": 177,
"content": "Extract all information with DeepSeek (remember to change base_url with https://api.deepseek.com/v1)"
},
"typeVersion": 1
},
{
"id": "af5e962c-4faf-41cc-a8b8-2fbb145b7af6",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-240,
-160
],
"parameters": {
"width": 501.28903654485043,
"height": 195.84053156146172,
"content": "Check if the review has already been saved to Google Drive"
},
"typeVersion": 1
},
{
"id": "400dff0c-8b2e-4fe2-933e-1f4d14624ca1",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
40,
80
],
"parameters": {
"width": 301.27574750830576,
"height": 177.34219269102988,
"content": "Analyze review sentiment"
},
"typeVersion": 1
},
{
"id": "52757ade-4206-40f9-bf4f-c3aefb004d2e",
"name": "Set Parameters",
"type": "n8n-nodes-base.set",
"position": [
-440,
-380
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "556e201d-242a-4c0e-bc13-787c2b60f800",
"name": "company_id",
"type": "string",
"value": "COMPANY"
},
{
"id": "a1f239df-df08-41d8-8b78-d6502266a581",
"name": "max_page",
"type": "number",
"value": 2
}
]
}
},
"typeVersion": 3.4
},
{
"id": "cd7e9d36-7ecd-4d9c-b552-8f46b0cfcc03",
"name": "Get reviews",
"type": "n8n-nodes-base.httpRequest",
"position": [
-200,
-380
],
"parameters": {
"url": "=https://it.trustpilot.com/review/{{ $json.company_id }}",
"options": {
"pagination": {
"pagination": {
"parameters": {
"parameters": [
{
"name": "page",
"value": "={{ $pageCount + 1 }}"
}
]
},
"maxRequests": "={{ $json.max_page }}",
"requestInterval": 5000,
"limitPagesFetched": true
}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "sort",
"value": "recency"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "476ff7b6-ab30-4674-a7fe-b032128ee51a",
"name": "Extract",
"type": "n8n-nodes-base.html",
"position": [
60,
-380
],
"parameters": {
"options": {},
"operation": "extractHtmlContent",
"extractionValues": {
"values": [
{
"key": "recensioni",
"attribute": "href",
"cssSelector": "article section a",
"returnArray": true,
"returnValue": "attribute"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "a2a35455-7d3e-4c4c-aa66-6cbbd48d867a",
"name": "Get rows",
"type": "n8n-nodes-base.googleSheets",
"position": [
-200,
-100
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $('Split Out').item.json.recensioni.replace('/reviews/','') }}",
"lookupColumn": "Id"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "",
"cachedResultName": "Foglio1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1QZhQqg79-HVBQh8Y2ihMq67UIYIRrJFKLQalcFvtDaY",
"cachedResultUrl": "",
"cachedResultName": "Trustpilot Review"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "JYR6a64Qecd6t8Hb",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "2d507fe6-a4fc-42ff-97ff-dfd552c651ab",
"name": "Get Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
-440,
-100
],
"parameters": {
"columns": {
"value": {
"Id": "={{ $('Split Out').item.json.recensioni.replace('/reviews/','') }}"
},
"schema": [
{
"id": "Id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Data",
"type": "string",
"display": true,
"required": false,
"displayName": "Data",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Nome",
"type": "string",
"display": true,
"required": false,
"displayName": "Nome",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Titolo",
"type": "string",
"display": true,
"required": false,
"displayName": "Titolo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Testo",
"type": "string",
"display": true,
"required": false,
"displayName": "Testo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Localit\u00e0",
"type": "string",
"display": true,
"required": false,
"displayName": "Localit\u00e0",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "N. Recensioni",
"type": "string",
"display": true,
"required": false,
"displayName": "N. Recensioni",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "URL",
"type": "string",
"display": true,
"required": false,
"displayName": "URL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Valutazione",
"type": "string",
"display": true,
"required": false,
"displayName": "Valutazione",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Sentiment",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Sentiment",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "",
"cachedResultName": "Foglio1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1QZhQqg79-HVBQh8Y2ihMq67UIYIRrJFKLQalcFvtDaY",
"cachedResultUrl": "",
"cachedResultName": "Trustpilot Reviews"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "JYR6a64Qecd6t8Hb",
"name": "Google Sheets account"
}
},
"executeOnce": false,
"typeVersion": 4.5
},
{
"id": "0a1fab6e-96b7-403b-884e-f67be6e23fa5",
"name": "Get Single review",
"type": "n8n-nodes-base.httpRequest",
"position": [
320,
-120
],
"parameters": {
"url": "=https://it.trustpilot.com{{ $('Split Out').item.json.recensioni }}",
"options": {}
},
"typeVersion": 4.2,
"alwaysOutputData": false
},
{
"id": "7d322d76-1032-405a-9d46-2958761a184d",
"name": "Extract review",
"type": "n8n-nodes-base.html",
"position": [
540,
-120
],
"parameters": {
"options": {},
"operation": "extractHtmlContent",
"extractionValues": {
"values": [
{
"key": "recensione",
"cssSelector": "article",
"returnArray": true
}
]
}
},
"typeVersion": 1.2
},
{
"id": "952484e5-8e87-4eb3-99a6-5bf26c701ba8",
"name": "Update sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
520,
120
],
"parameters": {
"columns": {
"value": {
"Id": "={{ $('Split Out').item.json.recensioni.replace('/reviews/','') }}",
"URL": "=https://it.trustpilot.com{{ $('Split Out').item.json.recensioni }}",
"Data": "={{ $('Information Extractor').item.json.output.data }}",
"Nome": "={{ $json.output.autore }}",
"Testo": "={{ $('Information Extractor').item.json.output.testo }}",
"Titolo": "={{ $('Information Extractor').item.json.output.titolo }}",
"Localit\u00e0": "={{ $('Information Extractor').item.json.output.nazione }}",
"Sentiment": "={{ $json.sentimentAnalysis.category }}",
"Valutazione": "={{ $('Information Extractor').item.json.output.valutazione }}",
"N. Recensioni": "={{ $('Information Extractor').item.json.output.n_recensioni }}"
},
"schema": [
{
"id": "Id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Data",
"type": "string",
"display": true,
"required": false,
"displayName": "Data",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Nome",
"type": "string",
"display": true,
"required": false,
"displayName": "Nome",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Titolo",
"type": "string",
"display": true,
"required": false,
"displayName": "Titolo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Testo",
"type": "string",
"display": true,
"required": false,
"displayName": "Testo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Localit\u00e0",
"type": "string",
"display": true,
"required": false,
"displayName": "Localit\u00e0",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "N. Recensioni",
"type": "string",
"display": true,
"required": false,
"displayName": "N. Recensioni",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "URL",
"type": "string",
"display": true,
"required": false,
"displayName": "URL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Valutazione",
"type": "string",
"display": true,
"required": false,
"displayName": "Valutazione",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Sentiment",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Sentiment",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "",
"cachedResultName": "Foglio1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1QZhQqg79-HVBQh8Y2ihMq67UIYIRrJFKLQalcFvtDaY",
"cachedResultUrl": "",
"cachedResultName": "Trustpilot Reviews"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "JYR6a64Qecd6t8Hb",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "eb853885-816d-4df7-b5ac-900fa89d3df9",
"name": "Sentiment Analysis",
"type": "@n8n/n8n-nodes-langchain.sentimentAnalysis",
"position": [
60,
140
],
"parameters": {
"options": {
"categories": "Positive, Neutral, Negative",
"systemPromptTemplate": "You are highly intelligent and accurate sentiment analyzer. Analyze the sentiment of the provided text. Categorize it into one of the following: {categories}. Use the provided formatting instructions. Only output the JSON."
},
"inputText": "={{ $json.output.testo }}"
},
"typeVersion": 1
},
{
"id": "79f1b9ea-6297-4735-9c0f-9f28dd65efa0",
"name": "DeepSeek Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
-460,
320
],
"parameters": {
"model": "deepseek-reasoner",
"options": {
"baseURL": "https://api.deepseek.com/v1"
}
},
"credentials": {
"openAiApi": {
"id": "97Cz4cqyiy1RdcQL",
"name": "DeepSeek"
}
},
"typeVersion": 1
},
{
"id": "159cc88e-1dd3-4bba-a3c8-59a9aad14c88",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
40,
320
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "CDX6QM4gLYanh0P4",
"name": "OpenAi account"
}
},
"typeVersion": 1.1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "43c8ee74-159c-4217-9cb4-554c63a3b183",
"connections": {
"If": {
"main": [
[
{
"node": "Get Single review",
"type": "main",
"index": 0
}
]
]
},
"Limit1": {
"main": [
[
{
"node": "Get Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Extract": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"Get rows": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "Limit1",
"type": "main",
"index": 0
}
]
]
},
"Get reviews": {
"main": [
[
{
"node": "Extract",
"type": "main",
"index": 0
}
]
]
},
"Extract review": {
"main": [
[
{
"node": "Information Extractor",
"type": "main",
"index": 0
}
]
]
},
"Set Parameters": {
"main": [
[
{
"node": "Get reviews",
"type": "main",
"index": 0
}
]
]
},
"Get Google Sheets": {
"main": [
[
{
"node": "Get rows",
"type": "main",
"index": 0
}
]
]
},
"Get Single review": {
"main": [
[
{
"node": "Extract review",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Sentiment Analysis",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Sentiment Analysis": {
"main": [
[
{
"node": "Update sheet",
"type": "main",
"index": 0
}
],
[
{
"node": "Update sheet",
"type": "main",
"index": 0
}
],
[
{
"node": "Update sheet",
"type": "main",
"index": 0
}
]
]
},
"DeepSeek Chat Model": {
"ai_languageModel": [
[
{
"node": "Information Extractor",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Information Extractor": {
"main": [
[
{
"node": "Sentiment Analysis",
"type": "main",
"index": 0
}
]
]
},
"When clicking \u2018Test workflow\u2019": {
"main": [
[
{
"node": "Set Parameters",
"type": "main",
"index": 0
}
]
]
}
}
}

View File

@@ -0,0 +1,748 @@
{
"id": "ThLx9WKLEujJHrvW",
"meta": {
"instanceId": "f047839feca8ac8518cd22514bc718f9790615975a10271981c34822b5cd9b5b",
"templateCredsSetupCompleted": true
},
"name": "Github Releases",
"tags": [],
"nodes": [
{
"id": "597d4aa3-e56a-4831-a0a8-6414e6e56de3",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
600,
380
],
"parameters": {},
"typeVersion": 1
},
{
"id": "731ac3c8-9c24-4f73-aad1-f96f359cf0f7",
"name": "Loop",
"type": "n8n-nodes-base.splitInBatches",
"position": [
40,
255
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "150d10c1-97ee-48b2-8d78-0bcce9776f7c",
"name": "Edit Fields",
"type": "n8n-nodes-base.set",
"position": [
1440,
560
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "7cbf2c0f-f242-4106-95c3-684d1b0959b1",
"name": "name",
"type": "string",
"value": "={{ $('Loop').item.json.name }}"
},
{
"id": "cdd6bd5d-d4b8-4656-8b01-1521f870b3d9",
"name": "title",
"type": "string",
"value": "={{ $('Limit').item.json.title }}"
},
{
"id": "61164f4d-d97c-4588-a54a-81b230b2cf3b",
"name": "link",
"type": "string",
"value": "={{ $('Limit').item.json.link }}"
},
{
"id": "f1b1717b-4689-4356-8deb-f103a69af0e1",
"name": "pubDate",
"type": "string",
"value": "={{ $('Limit').item.json.pubDate }}"
},
{
"id": "ec9394a9-5adb-4a00-92ca-b4a52f742ac0",
"name": "contentSnippet",
"type": "string",
"value": "={{ $('Limit').item.json.contentSnippet }}"
},
{
"id": "678d9b68-f5a5-4968-a5dc-827c3dd0fcfb",
"name": "id",
"type": "string",
"value": "={{ $('Limit').item.json.id }}"
},
{
"id": "d57a1455-b5d6-4caa-870c-0a4fac317932",
"name": "github",
"type": "string",
"value": "={{ $('Loop').item.json.github }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "c65ab032-a35a-4a00-89ed-de897d45b62f",
"name": "Cron Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-840,
260
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 */10 9-23 * * *"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "ebe92d40-a4a3-49fa-ae49-c1d0b87fcc0d",
"name": "GitHub Config",
"type": "n8n-nodes-base.code",
"position": [
-400,
260
],
"parameters": {
"jsCode": "return [\n {\n \"name\": \"n8n\",\n \"github\": \"n8n-io/n8n\"\n },\n {\n \"name\": \"Roo-Code\",\n \"github\": \"RooVetGit/Roo-Code\"\n },\n {\n \"name\": \"LobeChat\",\n \"github\": \"lobehub/lobe-chat\"\n },\n {\n \"name\": \"New API\",\n \"github\": \"Calcium-Ion/new-api\"\n },\n {\n \"name\": \"ChatWise\",\n \"github\": \"egoist/chatwise-releases\"\n },\n {\n \"name\": \"Folo\",\n \"github\": \"RSSNext/Folo\"\n },\n {\n \"name\": \"Clash Verge Rev\",\n \"github\": \"clash-verge-rev/clash-verge-rev\"\n },\n {\n \"name\": \"Cherry Studio\",\n \"github\": \"CherryHQ/cherry-studio\"\n }\n];"
},
"notesInFlow": false,
"typeVersion": 2
},
{
"id": "4e659c3f-3fa4-42c8-aceb-9ea18dfcff0f",
"name": "If No Error",
"type": "n8n-nodes-base.if",
"position": [
420,
380
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "56f4a7f3-7823-4794-ad74-bac41ef85d83",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json.error }}",
"rightValue": 0
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "f9ccdc63-06ae-47d0-8429-7a2b63d8c38a",
"name": "If New",
"type": "n8n-nodes-base.if",
"position": [
940,
380
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "ed896551-f486-4a1f-8585-8660f3a4a9bd",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.cache }}",
"rightValue": "={{ $('Limit').item.json.id }}"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "caf31152-18f0-4bf7-b09c-f76ba05dec5b",
"name": "Null",
"type": "n8n-nodes-base.set",
"position": [
1200,
560
],
"parameters": {
"options": {}
},
"typeVersion": 3.4
},
{
"id": "1fe3264a-2db3-4d5c-b800-182e15a8a355",
"name": "Send Error",
"type": "n8n-nodes-base.slack",
"position": [
620,
560
],
"webhookId": "eaf921a6-4cc9-472f-bdf3-dd24db51c769",
"parameters": {
"text": "=:x: *`{{ $('Loop').item.json.name }}`* Error\n\n> {{ $json.error }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C08ME7TDZ3J",
"cachedResultName": "github-release"
},
"otherOptions": {
"mrkdwn": true,
"sendAsUser": "Release Bot",
"unfurl_links": false,
"includeLinkToWorkflow": false
}
},
"credentials": {
"slackApi": {
"id": "NG6LWZ4Leh25N3VZ",
"name": "波特科技"
}
},
"typeVersion": 2.2
},
{
"id": "970c3556-abf9-402f-85bc-b80da949ce0b",
"name": "If Not Empty",
"type": "n8n-nodes-base.if",
"position": [
220,
240
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "4fdc7d1e-68f6-45ea-af6e-59a1eddbf214",
"operator": {
"type": "object",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "0425dbee-461f-4fdb-a9d2-4f78beb61826",
"name": "Date Format",
"type": "n8n-nodes-base.dateTime",
"position": [
780,
240
],
"parameters": {
"date": "={{ $('Loop').item.json.pubDate }}",
"format": "custom",
"options": {
"timezone": true
},
"operation": "formatDate",
"customFormat": "yyyy-MM-dd HH:mm"
},
"typeVersion": 2
},
{
"id": "a06e7050-1f84-4083-9cd3-a6c4f2dd25f3",
"name": "Information Extractor",
"type": "@n8n/n8n-nodes-langchain.informationExtractor",
"position": [
440,
240
],
"parameters": {
"text": "={{ $json.contentSnippet }}",
"options": {
"systemPromptTemplate": "You are an expert extraction algorithm.\nOnly extract relevant information from the text.\nIf you do not know the value of an attribute asked to extract, you may omit the attribute's value.\n\nYou need to analyze GitHub Release:\n\n1. Parse input content and identify all change items\n2. Filter out:\n - Contributor handles (@username)\n - Version numbers\n - Appreciation/congratulatory statements\n3. Categorize into:\n - features: New functionalities\n - fixes: Bug fixes\n - others: Documentation, configurations, etc.\n4. Language conversion:\n - Translate English descriptions to Chinese\n - Technical terms can remain in English but must use Chinese syntax\n5. Maintain original meaning with necessary simplification:\n - Remove redundancies\n - Merge similar entries\n - Simplify technical jargon\n\nProhibited elements:\n1. Explanatory text\n2. Markdown formatting\n3. Uncategorized content\n4. Untranslated English items\n5. Empty category headers"
},
"schemaType": "fromJson",
"jsonSchemaExample": "{\n \"features\": [\n \"新增首页功能,默认启动页面改为首页\",\n \"新增 DNS 覆写功能,默认启用 DNS 覆写\"\n ],\n \"fixes\": [\n \"修复弹黑框的问题\",\n \"修复系统代理地址错误的问题\"\n ],\n \"others\": [\n \"重构后端,巨幅性能优化\",\n \"优化定时器管理\"\n ]\n}"
},
"typeVersion": 1
},
{
"id": "42ed9553-ed63-4554-b0c5-8b4d9a1e9ae9",
"name": "Send Message",
"type": "n8n-nodes-base.slack",
"position": [
1200,
240
],
"webhookId": "eaf921a6-4cc9-472f-bdf3-dd24db51c769",
"parameters": {
"text": "=Release - {{ $('If Not Empty').item.json.name }}",
"select": "channel",
"blocksUi": "={{ $json }}",
"channelId": {
"__rl": true,
"mode": "id",
"value": "C08ME7TDZ3J"
},
"messageType": "block",
"otherOptions": {
"mrkdwn": true,
"sendAsUser": "GitHub Release",
"unfurl_links": false,
"includeLinkToWorkflow": false
}
},
"credentials": {
"slackApi": {
"id": "NG6LWZ4Leh25N3VZ",
"name": "波特科技"
}
},
"typeVersion": 2.2
},
{
"id": "c4b89e3f-0c61-493d-8950-e77b56f38ca3",
"name": "Gemini",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
440,
100
],
"parameters": {
"options": {
"temperature": 0.3
},
"modelName": "models/gemini-2.0-flash-001"
},
"credentials": {
"googlePalmApi": {
"id": "wN3fB5ELQ7iJt3b8",
"name": "Gemini"
}
},
"typeVersion": 1
},
{
"id": "b3979529-5445-4d44-bd9e-69079b222b8d",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-560,
-140
],
"parameters": {
"width": 420,
"height": 540,
"content": "## GitHub Releases Config\n- Edit the JavaScript array within this node's code area.\n- Modify or add the repositories you want to follow. Each repository object needs a `name` (custom display name) and `github` (format: `owner/repo`).\n- Example:\n ```javascript\n {\n \"name\": \"n8n\", // Custom display name\n \"github\": \"n8n-io/n8n\" // GitHub path\n },\n {\n \"name\": \"LobeChat\",\n \"github\": \"lobehub/lobe-chat\"\n }\n // ... add more repositories\n ```"
},
"typeVersion": 1
},
{
"id": "ed1b69c4-cb95-424a-85e8-7de827b20e22",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-900,
80
],
"parameters": {
"width": 260,
"height": 340,
"content": "## Cron Trigger\nAdjust the `Rule` setting to change the update check frequency (default is `0 */10 9-23 * * *`, checking every 10 minutes between 9 AM and 11 PM daily)."
},
"typeVersion": 1
},
{
"id": "0ff16ac1-755d-4a83-a631-e6a8df4d14a6",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
380,
-220
],
"parameters": {
"width": 380,
"height": 580,
"content": "## Gemini (AI Model)\n- Select your configured Google Gemini credentials.\n- (Optional) Replace with a different supported AI model node and select its credentials.\n## Information Extractor \nAI Processing & Translation\n- **Main Configuration**: Review the `System Prompt`. By default, it asks the AI to extract information and translate it into **Chinese**. Modify this prompt if you need a different language or summary style."
},
"typeVersion": 1
},
{
"id": "6a985f02-105c-4f6e-a924-2289538dfdc0",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1140,
20
],
"parameters": {
"height": 380,
"content": "## Send Message\nSlack Notifications\n- Select your configured Slack credentials in both Slack nodes.\n- Set the target `Channel ID` for notifications."
},
"typeVersion": 1
},
{
"id": "80300633-feba-4f12-9ee6-2abba300a153",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
540
],
"parameters": {
"height": 340,
"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Send Error\n- Select your configured Slack credentials in both Slack nodes.\n- Set the target `Channel ID` for notifications."
},
"typeVersion": 1
},
{
"id": "9f671e1d-0b72-4e2c-ae80-f65a5aa56c1d",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1440,
-220
],
"parameters": {
"width": 460,
"height": 900,
"content": "## Prerequisites\n\n* **Redis**: Have an available Redis service and configure its credentials in n8n.\n* **AI Provider (Gemini)**: Configure credentials for Google Gemini (or your chosen AI model) in n8n.\n* **Slack**: Configure your Slack app credentials in n8n.\n\n## Slack Permissions Config\n- In the `Bot Token Scopes` section of the `OAuth & Permissions` menu, add the following permissions:\n - `chat:write`\n - `chat:write.customize`\n- Perform the `Install` (or Reinstall) operation in the `Install App` menu.\n- Obtain the `Bot User OAuth Token` and configure it in the credentials of n8n."
},
"typeVersion": 1
},
{
"id": "1b4274ec-0364-4c8d-b040-8882e48ab192",
"name": "Redis Set Id",
"type": "n8n-nodes-base.redis",
"position": [
1440,
240
],
"parameters": {
"key": "=github_release:{{ $('If Not Empty').item.json.github }}",
"value": "={{ $('If Not Empty').item.json.id }}",
"keyType": "string",
"operation": "set"
},
"credentials": {
"redis": {
"id": "qrUBdRWlD3Zuri46",
"name": "Redis account"
}
},
"typeVersion": 1
},
{
"id": "3a809420-5bee-4976-a57e-ca161677de76",
"name": "Code for Slack Tpl",
"type": "n8n-nodes-base.code",
"position": [
980,
240
],
"parameters": {
"jsCode": "function generateRichTextBlock(title, items) {\n return {\n type: \"rich_text\",\n elements: [\n {\n type: \"rich_text_section\",\n elements: [{ type: \"text\", text: `${title}:` }]\n },\n {\n type: \"rich_text_list\",\n style: \"bullet\",\n indent: 0,\n border: 0,\n elements: items.map(item => ({\n type: \"rich_text_section\",\n elements: [{ type: \"text\", text: item }]\n }))\n }\n ]\n };\n}\n\nfunction generateRichText(value, metadata) {\n if (!value || typeof value !== 'object') return [];\n\n const { name, link, title, formattedDate } = metadata;\n \n const baseBlocks = [\n {\n type: \"header\",\n text: {\n type: \"plain_text\",\n text: name\n }\n },\n {\n type: \"context\",\n elements: [{\n text: `${formattedDate} | <${link}|${title}>`,\n type: \"mrkdwn\"\n }]\n },\n { type: \"divider\" }\n ];\n\n const sections = [\n { key: \"features\", title: \"Features\" },\n { key: \"fixes\", title: \"Fixes\" },\n { key: \"others\", title: \"Others\" }\n ];\n\n const contentBlocks = sections\n .filter(({ key }) => Array.isArray(value[key]) && value[key].length > 0)\n .map(({ key, title }) => generateRichTextBlock(title, value[key]));\n\n return {\n blocks: [...baseBlocks, ...contentBlocks]\n };\n}\n\nfunction processAllItems(infoExtractor, ifNotEmpty, dateFormat) {\n return infoExtractor.all().map((item, index) => {\n const metadata = {\n name: ifNotEmpty.all()[index].json.name,\n link: ifNotEmpty.all()[index].json.link,\n title: ifNotEmpty.all()[index].json.title,\n formattedDate: dateFormat.all()[index].json.formattedDate\n };\n return generateRichText(item.json.output, metadata);\n });\n}\n\nreturn processAllItems(\n $('Information Extractor'),\n $('If Not Empty'), \n $('Date Format')\n);"
},
"typeVersion": 2
},
{
"id": "d11a10fc-c68b-4e2b-a00e-5d63ec38abf6",
"name": "RSS for Release",
"type": "n8n-nodes-base.rssFeedRead",
"onError": "continueRegularOutput",
"position": [
220,
380
],
"parameters": {
"url": "=https://github.com/{{ $json.github }}/releases.atom ",
"options": {}
},
"typeVersion": 1.1
},
{
"id": "e9691400-a3de-4267-93d8-f99469399e21",
"name": "Redis Get",
"type": "n8n-nodes-base.redis",
"position": [
780,
380
],
"parameters": {
"key": "=github_release:{{ $('Loop').item.json.github }}",
"keyType": "string",
"options": {
"dotNotation": false
},
"operation": "get",
"propertyName": "cache"
},
"credentials": {
"redis": {
"id": "qrUBdRWlD3Zuri46",
"name": "Redis account"
}
},
"typeVersion": 1
}
],
"active": true,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "19314a54-e5b4-49ef-a550-1cabb23c8104",
"connections": {
"Loop": {
"main": [
[
{
"node": "If Not Empty",
"type": "main",
"index": 0
}
],
[
{
"node": "RSS for Release",
"type": "main",
"index": 0
}
]
]
},
"Null": {
"main": [
[
{
"node": "Loop",
"type": "main",
"index": 0
}
]
]
},
"Limit": {
"main": [
[
{
"node": "Redis Get",
"type": "main",
"index": 0
}
]
]
},
"Gemini": {
"ai_languageModel": [
[
{
"node": "Information Extractor",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"If New": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
],
[
{
"node": "Null",
"type": "main",
"index": 0
}
]
]
},
"Redis Get": {
"main": [
[
{
"node": "If New",
"type": "main",
"index": 0
}
]
]
},
"Date Format": {
"main": [
[
{
"node": "Code for Slack Tpl",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "Loop",
"type": "main",
"index": 0
}
]
]
},
"If No Error": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Error",
"type": "main",
"index": 0
},
{
"node": "Null",
"type": "main",
"index": 0
}
]
]
},
"Cron Trigger": {
"main": [
[
{
"node": "GitHub Config",
"type": "main",
"index": 0
}
]
]
},
"If Not Empty": {
"main": [
[
{
"node": "Information Extractor",
"type": "main",
"index": 0
}
]
]
},
"Redis Set Id": {
"main": [
[]
]
},
"Send Message": {
"main": [
[
{
"node": "Redis Set Id",
"type": "main",
"index": 0
}
]
]
},
"GitHub Config": {
"main": [
[
{
"node": "Loop",
"type": "main",
"index": 0
}
]
]
},
"RSS for Release": {
"main": [
[
{
"node": "If No Error",
"type": "main",
"index": 0
}
]
]
},
"Code for Slack Tpl": {
"main": [
[
{
"node": "Send Message",
"type": "main",
"index": 0
}
]
]
},
"Information Extractor": {
"main": [
[
{
"node": "Date Format",
"type": "main",
"index": 0
}
]
]
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,839 @@
{
"id": "JxFP8FJ2W7e4Kmqn",
"meta": {
"instanceId": "fb8bc2e315f7f03c97140b30aa454a27bc7883a19000fa1da6e6b571bf56ad6d",
"templateCredsSetupCompleted": true
},
"name": "RAG on living data",
"tags": [],
"nodes": [
{
"id": "49086cdf-a38c-4cb8-9be9-d3e6ea5bdde5",
"name": "Embeddings OpenAI",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
1740,
1040
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "X7Jf0zECd3IkQdSw",
"name": "OpenAi (octionicsolutions)"
}
},
"typeVersion": 1
},
{
"id": "f0670721-92f4-422a-99c9-f9c2aa6fe21f",
"name": "Token Splitter",
"type": "@n8n/n8n-nodes-langchain.textSplitterTokenSplitter",
"position": [
2380,
540
],
"parameters": {
"chunkSize": 500
},
"typeVersion": 1
},
{
"id": "fe80ecac-4f79-4b07-ad8e-60ab5f980cba",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1180,
-200
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "81b79248-08e8-4214-872b-1796e51ad0a4",
"name": "Question and Answer Chain",
"type": "@n8n/n8n-nodes-langchain.chainRetrievalQa",
"position": [
744,
495
],
"parameters": {
"options": {}
},
"typeVersion": 1.3
},
{
"id": "e78f7b63-baef-4834-8f1b-aecfa9102d6c",
"name": "Vector Store Retriever",
"type": "@n8n/n8n-nodes-langchain.retrieverVectorStore",
"position": [
844,
715
],
"parameters": {},
"typeVersion": 1
},
{
"id": "1d5ffbd0-b2cf-4660-a291-581d18608ecd",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
704,
715
],
"parameters": {
"model": "gpt-4o",
"options": {}
},
"credentials": {
"openAiApi": {
"id": "X7Jf0zECd3IkQdSw",
"name": "OpenAi (octionicsolutions)"
}
},
"typeVersion": 1
},
{
"id": "37a3063f-aa21-4347-a72f-6dd316c58366",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
524,
495
],
"webhookId": "74479a54-418f-4de2-b70d-cfb3e3fdd5a7",
"parameters": {
"public": true,
"options": {}
},
"typeVersion": 1.1
},
{
"id": "5924bc01-1694-4b5c-8a06-7c46ee4c6425",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
520,
-200
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 1
}
]
}
},
"typeVersion": 1.2
},
{
"id": "5067eda6-8bbe-407a-a6af-93e81be53661",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
620,
0
],
"parameters": {
"width": 329.16412916774584,
"height": 312.52803480051045,
"content": "## Switch trigger (optional)\nIf you are on the cloud plan, consider switching to the Notion Trigger Node instead, to save on executions."
},
"typeVersion": 1
},
{
"id": "33458828-484d-426b-a3d1-974a81c6162e",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
1620,
-60
],
"parameters": {},
"typeVersion": 1
},
{
"id": "4d39503a-378e-4942-a5d4-8c62785aac44",
"name": "Limit1",
"type": "n8n-nodes-base.limit",
"position": [
2660,
-60
],
"parameters": {},
"typeVersion": 1
},
{
"id": "0e0b1391-3fe5-4d80-a2eb-a2483b79d9a6",
"name": "Delete old embeddings if exist",
"type": "n8n-nodes-base.supabase",
"position": [
1400,
-60
],
"parameters": {
"tableId": "documents",
"operation": "delete",
"filterType": "string",
"filterString": "=metadata->>id=eq.{{ $('Input Reference').item.json.id }}"
},
"credentials": {
"supabaseApi": {
"id": "DjIb4HMTYXhTU8Uc",
"name": "Supabase (VectorStore)"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "4a8614e4-0a53-4731-bc68-57505d7d0a09",
"name": "Get page blocks",
"type": "n8n-nodes-base.notion",
"position": [
1840,
-60
],
"parameters": {
"blockId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Input Reference').item.json.id }}"
},
"resource": "block",
"operation": "getAll",
"returnAll": true,
"fetchNestedBlocks": true
},
"credentials": {
"notionApi": {
"id": "ObmaBA0dJss3JJPv",
"name": "Notion (octionicsolutions / Test)"
}
},
"executeOnce": true,
"typeVersion": 2.2
},
{
"id": "8c922895-49d6-4778-8356-6f6cf49e5420",
"name": "Default Data Loader",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
2300,
260
],
"parameters": {
"options": {
"metadata": {
"metadataValues": [
{
"name": "id",
"value": "={{ $('Input Reference').item.json.id }}"
},
{
"name": "name",
"value": "={{ $('Input Reference').item.json.name }}"
}
]
}
}
},
"typeVersion": 1
},
{
"id": "8ad7ff2e-4bc2-4821-ae03-bab2dc11d947",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
2220,
400
],
"parameters": {
"width": 376.2098538932132,
"height": 264.37628764336097,
"content": "## Adjust chunk size and overlap\nFor more accurate search results, increase the overlap. For the *text-embedding-ada-002* model the chunk size plus overlap must not exceed 8191"
},
"typeVersion": 1
},
{
"id": "8078d59a-f45f-4e96-a8ec-6c2f1c328e84",
"name": "Input Reference",
"type": "n8n-nodes-base.noOp",
"position": [
960,
-200
],
"parameters": {},
"typeVersion": 1
},
{
"id": "aae6c517-a316-40e3-aee9-1cc4b448689f",
"name": "Notion Trigger",
"type": "n8n-nodes-base.notionTrigger",
"disabled": true,
"position": [
740,
120
],
"parameters": {
"event": "pagedUpdatedInDatabase",
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"databaseId": {
"__rl": true,
"mode": "list",
"value": "ec6dc7b4-9ce0-47f7-8025-ef09295999fd",
"cachedResultUrl": "https://www.notion.so/ec6dc7b49ce047f78025ef09295999fd",
"cachedResultName": "Knowledge Base"
}
},
"credentials": {
"notionApi": {
"id": "ObmaBA0dJss3JJPv",
"name": "Notion (octionicsolutions / Test)"
}
},
"typeVersion": 1
},
{
"id": "3a43d66d-d4e3-4ca1-aee9-85ac65160e45",
"name": "Get updated pages",
"type": "n8n-nodes-base.notion",
"position": [
740,
-200
],
"parameters": {
"filters": {
"conditions": [
{
"key": "Last edited time|last_edited_time",
"condition": "equals",
"lastEditedTime": "={{ $now.minus(1, 'minutes').toISO() }}"
}
]
},
"options": {},
"resource": "databasePage",
"operation": "getAll",
"databaseId": {
"__rl": true,
"mode": "list",
"value": "ec6dc7b4-9ce0-47f7-8025-ef09295999fd",
"cachedResultUrl": "https://www.notion.so/ec6dc7b49ce047f78025ef09295999fd",
"cachedResultName": "Knowledge Base"
},
"filterType": "manual"
},
"credentials": {
"notionApi": {
"id": "ObmaBA0dJss3JJPv",
"name": "Notion (octionicsolutions / Test)"
}
},
"typeVersion": 2.2
},
{
"id": "bbf1296f-4e2b-4a38-bdf3-ae2b63cc7774",
"name": "Sticky Note23",
"type": "n8n-nodes-base.stickyNote",
"position": [
900,
-300
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "This placeholder serves as a reference point so it is easier to swap the data source with a different service"
},
"typeVersion": 1
},
{
"id": "631e1e10-0b52-4a17-89a4-769ac563321f",
"name": "Sticky Note24",
"type": "n8n-nodes-base.stickyNote",
"position": [
1340,
-160
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "All chunks of a previous version of the document are being deleted by filtering the meta data by the given ID"
},
"typeVersion": 1
},
{
"id": "6c830c83-4b70-4719-8e2a-26846e60085c",
"name": "Sticky Note25",
"type": "n8n-nodes-base.stickyNote",
"position": [
1560,
-160
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Reduce the active streams/items to just 1 to prevent the following nodes from double-processing"
},
"typeVersion": 1
},
{
"id": "46c8e4e4-0a5e-4ede-947b-5773710d4e55",
"name": "Sticky Note26",
"type": "n8n-nodes-base.stickyNote",
"position": [
1780,
-160
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Retrieve all page contents/blocks"
},
"typeVersion": 1
},
{
"id": "0369e610-d074-4812-9d04-8615b42965a5",
"name": "Sticky Note27",
"type": "n8n-nodes-base.stickyNote",
"position": [
2600,
-160
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Reduce the active streams/items to just 1 to prevent the following nodes from double-processing"
},
"typeVersion": 1
},
{
"id": "4f3bce54-1650-45fa-abb0-c881358c7e8d",
"name": "Sticky Note28",
"type": "n8n-nodes-base.stickyNote",
"position": [
2220,
-160
],
"parameters": {
"color": 7,
"width": 375.9283286479995,
"height": 275.841854198618,
"content": "Embed item and store in Vector Store. Depending on the length the content is being split up into multiple chunks/embeds"
},
"typeVersion": 1
},
{
"id": "44125921-e068-4a5d-a56b-b0e63c103556",
"name": "Supabase Vector Store1",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
924,
935
],
"parameters": {
"options": {},
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
}
},
"credentials": {
"supabaseApi": {
"id": "DjIb4HMTYXhTU8Uc",
"name": "Supabase (VectorStore)"
}
},
"typeVersion": 1
},
{
"id": "467322a9-949d-4569-aac6-92196da46ba5",
"name": "Sticky Note30",
"type": "n8n-nodes-base.stickyNote",
"position": [
460,
400
],
"parameters": {
"color": 7,
"width": 730.7522093855692,
"height": 668.724737081502,
"content": "Simple chat bot to ask specific questions while having access to the context of the Notion Knowledge Base which was stored in the Vector Store"
},
"typeVersion": 1
},
{
"id": "27f078cf-b309-4dd1-a8ce-b4fc504d6e29",
"name": "Sticky Note31",
"type": "n8n-nodes-base.stickyNote",
"position": [
1660,
900
],
"parameters": {
"color": 7,
"width": 219.31927574471658,
"height": 275.841854198618,
"content": "Model used for both creating and reading embeddings"
},
"typeVersion": 1
},
{
"id": "2f59cba1-4318-47e7-bf0b-b908d4186b86",
"name": "Supabase Vector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
2280,
-60
],
"parameters": {
"mode": "insert",
"options": {},
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
}
},
"credentials": {
"supabaseApi": {
"id": "DjIb4HMTYXhTU8Uc",
"name": "Supabase (VectorStore)"
}
},
"typeVersion": 1
},
{
"id": "729849e7-0eff-40c2-ae00-ae660c1eec69",
"name": "Sticky Note32",
"type": "n8n-nodes-base.stickyNote",
"position": [
1120,
-300
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Process each page/document separately."
},
"typeVersion": 1
},
{
"id": "3f632a24-ca0a-45c4-801d-041aa3f887a7",
"name": "Sticky Note29",
"type": "n8n-nodes-base.stickyNote",
"position": [
2220,
120
],
"parameters": {
"color": 7,
"width": 376.0759088111347,
"height": 275.841854198618,
"content": "Store additional meta data with each embed, especially the Notion ID, which can be later used to find all belonging entries of one page, even if they got split into multiple embeds."
},
"typeVersion": 1
},
{
"id": "ffaf3861-5287-4f57-8372-09216a18cb4d",
"name": "Sticky Note33",
"type": "n8n-nodes-base.stickyNote",
"position": [
460,
-300
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Using a manual approach for polling data from Notion for more accuracy."
},
"typeVersion": 1
},
{
"id": "cbbedfc0-4d64-42a6-8f55-21e04887305f",
"name": "Sticky Note34",
"type": "n8n-nodes-base.stickyNote",
"position": [
680,
-300
],
"parameters": {
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "## Select Database\nChoose the database which represents your Knowledge Base"
},
"typeVersion": 1
},
{
"id": "8b6767f2-1bc9-42fb-b319-f39f6734b9f2",
"name": "Sticky Note35",
"type": "n8n-nodes-base.stickyNote",
"position": [
2000,
-160
],
"parameters": {
"color": 7,
"width": 216.47293010628914,
"height": 275.841854198618,
"content": "Combine all contents to a single text formatted into one line which can be easily stored as an embed"
},
"typeVersion": 1
},
{
"id": "cdff1756-77d7-421e-8672-25c9862840b0",
"name": "Concatenate to single string",
"type": "n8n-nodes-base.summarize",
"position": [
2060,
-60
],
"parameters": {
"options": {},
"fieldsToSummarize": {
"values": [
{
"field": "content",
"separateBy": "\n",
"aggregation": "concatenate"
}
]
}
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "51075175-868a-4a3a-9580-5ad55e25ac71",
"connections": {
"Limit": {
"main": [
[
{
"node": "Get page blocks",
"type": "main",
"index": 0
}
]
]
},
"Limit1": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Notion Trigger": {
"main": [
[
{
"node": "Input Reference",
"type": "main",
"index": 0
}
]
]
},
"Token Splitter": {
"ai_textSplitter": [
[
{
"node": "Default Data Loader",
"type": "ai_textSplitter",
"index": 0
}
]
]
},
"Get page blocks": {
"main": [
[
{
"node": "Concatenate to single string",
"type": "main",
"index": 0
}
]
]
},
"Input Reference": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Delete old embeddings if exist",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get updated pages",
"type": "main",
"index": 0
}
]
]
},
"Embeddings OpenAI": {
"ai_embedding": [
[
{
"node": "Supabase Vector Store",
"type": "ai_embedding",
"index": 0
},
{
"node": "Supabase Vector Store1",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Get updated pages": {
"main": [
[
{
"node": "Input Reference",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Question and Answer Chain",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Default Data Loader": {
"ai_document": [
[
{
"node": "Supabase Vector Store",
"type": "ai_document",
"index": 0
}
]
]
},
"Supabase Vector Store": {
"main": [
[
{
"node": "Limit1",
"type": "main",
"index": 0
}
]
]
},
"Supabase Vector Store1": {
"ai_vectorStore": [
[
{
"node": "Vector Store Retriever",
"type": "ai_vectorStore",
"index": 0
}
]
]
},
"Vector Store Retriever": {
"ai_retriever": [
[
{
"node": "Question and Answer Chain",
"type": "ai_retriever",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "Question and Answer Chain",
"type": "main",
"index": 0
}
]
]
},
"Concatenate to single string": {
"main": [
[
{
"node": "Supabase Vector Store",
"type": "main",
"index": 0
}
]
]
},
"Delete old embeddings if exist": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
]
]
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,920 @@
{
"id": "w434EiZ2z7klQAyp",
"meta": {
"instanceId": "a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462",
"templateCredsSetupCompleted": true
},
"name": "Scrape Trustpilot Reviews with DeepSeek, Analyze Sentiment with OpenAI",
"tags": [
{
"id": "2VG6RbmUdJ2VZbrj",
"name": "Google Drive",
"createdAt": "2024-12-04T16:50:56.177Z",
"updatedAt": "2024-12-04T16:50:56.177Z"
},
{
"id": "paTcf5QZDJsC2vKY",
"name": "OpenAI",
"createdAt": "2024-12-04T16:52:10.768Z",
"updatedAt": "2024-12-04T16:52:10.768Z"
}
],
"nodes": [
{
"id": "095a8e10-1630-4a1a-b6c9-7950ae1ed803",
"name": "Split Out",
"type": "n8n-nodes-base.splitOut",
"position": [
320,
-380
],
"parameters": {
"options": {},
"fieldToSplitOut": "recensioni"
},
"typeVersion": 1
},
{
"id": "6ff4dd9d-eedd-4d84-b13a-b3c0db717409",
"name": "Information Extractor",
"type": "@n8n/n8n-nodes-langchain.informationExtractor",
"position": [
-440,
140
],
"parameters": {
"text": "=You need to extract the review from the following HTML: {{ $json.recensione }}",
"options": {
"systemPromptTemplate": "You are a review expert. You need to extract only the required information and report it without changing anything.\nAll the required information is in the text."
},
"attributes": {
"attributes": [
{
"name": "autore",
"required": true,
"description": "Extract the name of the review author"
},
{
"name": "valutazione",
"type": "number",
"required": true,
"description": "Extract the rating given to the review (from 1 to 5)"
},
{
"name": "data",
"required": true,
"description": "Extract review date in YYYY-MM-DD format"
},
{
"name": "titolo",
"required": true,
"description": "Extract the review title"
},
{
"name": "testo",
"required": true,
"description": "Extract the review text"
},
{
"name": "n_recensioni",
"type": "number",
"required": true,
"description": "Extract the total number of reviews made by the user"
},
{
"name": "nazione",
"required": true,
"description": "Extract the country of the user who wrote the review. Must be two characters"
}
]
}
},
"typeVersion": 1
},
{
"id": "0036f3b1-4832-4a35-8694-0893475a4119",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
60,
-100
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "ab666549-4eec-40e2-a702-0575c094a2d4",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json.Valutazione }}",
"rightValue": "={{ $('Split Out').item.json.recensioni.replace('/reviews/','') }}"
}
]
},
"looseTypeValidation": true
},
"executeOnce": false,
"typeVersion": 2.2
},
{
"id": "5423b55d-eb6c-41c6-9b26-410e3c92b85d",
"name": "When clicking Test workflow",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-700,
-380
],
"parameters": {},
"typeVersion": 1
},
{
"id": "506cdaa1-e0ba-4f29-b137-69d321b13c94",
"name": "Limit1",
"type": "n8n-nodes-base.limit",
"position": [
540,
-380
],
"parameters": {
"maxItems": 3
},
"typeVersion": 1
},
{
"id": "40f1e30d-8aed-4995-b4e4-2239248bd6e7",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-460,
-480
],
"parameters": {
"width": 212.25249169435213,
"height": 245.55481727574733,
"content": "Change to the name of the company registered on Trustpilot and the maximum number of pages to scrape"
},
"typeVersion": 1
},
{
"id": "e6d2fec1-7255-4270-86b4-6d6f39f44ccb",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-460,
80
],
"parameters": {
"width": 381,
"height": 177,
"content": "Extract all information with DeepSeek (remember to change base_url with https://api.deepseek.com/v1)"
},
"typeVersion": 1
},
{
"id": "af5e962c-4faf-41cc-a8b8-2fbb145b7af6",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-240,
-160
],
"parameters": {
"width": 501.28903654485043,
"height": 195.84053156146172,
"content": "Check if the review has already been saved to Google Drive"
},
"typeVersion": 1
},
{
"id": "400dff0c-8b2e-4fe2-933e-1f4d14624ca1",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
40,
80
],
"parameters": {
"width": 301.27574750830576,
"height": 177.34219269102988,
"content": "Analyze review sentiment"
},
"typeVersion": 1
},
{
"id": "52757ade-4206-40f9-bf4f-c3aefb004d2e",
"name": "Set Parameters",
"type": "n8n-nodes-base.set",
"position": [
-440,
-380
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "556e201d-242a-4c0e-bc13-787c2b60f800",
"name": "company_id",
"type": "string",
"value": "COMPANY"
},
{
"id": "a1f239df-df08-41d8-8b78-d6502266a581",
"name": "max_page",
"type": "number",
"value": 2
}
]
}
},
"typeVersion": 3.4
},
{
"id": "cd7e9d36-7ecd-4d9c-b552-8f46b0cfcc03",
"name": "Get reviews",
"type": "n8n-nodes-base.httpRequest",
"position": [
-200,
-380
],
"parameters": {
"url": "=https://it.trustpilot.com/review/{{ $json.company_id }}",
"options": {
"pagination": {
"pagination": {
"parameters": {
"parameters": [
{
"name": "page",
"value": "={{ $pageCount + 1 }}"
}
]
},
"maxRequests": "={{ $json.max_page }}",
"requestInterval": 5000,
"limitPagesFetched": true
}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "sort",
"value": "recency"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "476ff7b6-ab30-4674-a7fe-b032128ee51a",
"name": "Extract",
"type": "n8n-nodes-base.html",
"position": [
60,
-380
],
"parameters": {
"options": {},
"operation": "extractHtmlContent",
"extractionValues": {
"values": [
{
"key": "recensioni",
"attribute": "href",
"cssSelector": "article section a",
"returnArray": true,
"returnValue": "attribute"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "a2a35455-7d3e-4c4c-aa66-6cbbd48d867a",
"name": "Get rows",
"type": "n8n-nodes-base.googleSheets",
"position": [
-200,
-100
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $('Split Out').item.json.recensioni.replace('/reviews/','') }}",
"lookupColumn": "Id"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "",
"cachedResultName": "Foglio1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1QZhQqg79-HVBQh8Y2ihMq67UIYIRrJFKLQalcFvtDaY",
"cachedResultUrl": "",
"cachedResultName": "Trustpilot Review"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "JYR6a64Qecd6t8Hb",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "2d507fe6-a4fc-42ff-97ff-dfd552c651ab",
"name": "Get Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
-440,
-100
],
"parameters": {
"columns": {
"value": {
"Id": "={{ $('Split Out').item.json.recensioni.replace('/reviews/','') }}"
},
"schema": [
{
"id": "Id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Data",
"type": "string",
"display": true,
"required": false,
"displayName": "Data",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Nome",
"type": "string",
"display": true,
"required": false,
"displayName": "Nome",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Titolo",
"type": "string",
"display": true,
"required": false,
"displayName": "Titolo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Testo",
"type": "string",
"display": true,
"required": false,
"displayName": "Testo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Località",
"type": "string",
"display": true,
"required": false,
"displayName": "Località",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "N. Recensioni",
"type": "string",
"display": true,
"required": false,
"displayName": "N. Recensioni",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "URL",
"type": "string",
"display": true,
"required": false,
"displayName": "URL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Valutazione",
"type": "string",
"display": true,
"required": false,
"displayName": "Valutazione",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Sentiment",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Sentiment",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "",
"cachedResultName": "Foglio1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1QZhQqg79-HVBQh8Y2ihMq67UIYIRrJFKLQalcFvtDaY",
"cachedResultUrl": "",
"cachedResultName": "Trustpilot Reviews"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "JYR6a64Qecd6t8Hb",
"name": "Google Sheets account"
}
},
"executeOnce": false,
"typeVersion": 4.5
},
{
"id": "0a1fab6e-96b7-403b-884e-f67be6e23fa5",
"name": "Get Single review",
"type": "n8n-nodes-base.httpRequest",
"position": [
320,
-120
],
"parameters": {
"url": "=https://it.trustpilot.com{{ $('Split Out').item.json.recensioni }}",
"options": {}
},
"typeVersion": 4.2,
"alwaysOutputData": false
},
{
"id": "7d322d76-1032-405a-9d46-2958761a184d",
"name": "Extract review",
"type": "n8n-nodes-base.html",
"position": [
540,
-120
],
"parameters": {
"options": {},
"operation": "extractHtmlContent",
"extractionValues": {
"values": [
{
"key": "recensione",
"cssSelector": "article",
"returnArray": true
}
]
}
},
"typeVersion": 1.2
},
{
"id": "952484e5-8e87-4eb3-99a6-5bf26c701ba8",
"name": "Update sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
520,
120
],
"parameters": {
"columns": {
"value": {
"Id": "={{ $('Split Out').item.json.recensioni.replace('/reviews/','') }}",
"URL": "=https://it.trustpilot.com{{ $('Split Out').item.json.recensioni }}",
"Data": "={{ $('Information Extractor').item.json.output.data }}",
"Nome": "={{ $json.output.autore }}",
"Testo": "={{ $('Information Extractor').item.json.output.testo }}",
"Titolo": "={{ $('Information Extractor').item.json.output.titolo }}",
"Località": "={{ $('Information Extractor').item.json.output.nazione }}",
"Sentiment": "={{ $json.sentimentAnalysis.category }}",
"Valutazione": "={{ $('Information Extractor').item.json.output.valutazione }}",
"N. Recensioni": "={{ $('Information Extractor').item.json.output.n_recensioni }}"
},
"schema": [
{
"id": "Id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Data",
"type": "string",
"display": true,
"required": false,
"displayName": "Data",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Nome",
"type": "string",
"display": true,
"required": false,
"displayName": "Nome",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Titolo",
"type": "string",
"display": true,
"required": false,
"displayName": "Titolo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Testo",
"type": "string",
"display": true,
"required": false,
"displayName": "Testo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Località",
"type": "string",
"display": true,
"required": false,
"displayName": "Località",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "N. Recensioni",
"type": "string",
"display": true,
"required": false,
"displayName": "N. Recensioni",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "URL",
"type": "string",
"display": true,
"required": false,
"displayName": "URL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Valutazione",
"type": "string",
"display": true,
"required": false,
"displayName": "Valutazione",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Sentiment",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Sentiment",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "",
"cachedResultName": "Foglio1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1QZhQqg79-HVBQh8Y2ihMq67UIYIRrJFKLQalcFvtDaY",
"cachedResultUrl": "",
"cachedResultName": "Trustpilot Reviews"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "JYR6a64Qecd6t8Hb",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "eb853885-816d-4df7-b5ac-900fa89d3df9",
"name": "Sentiment Analysis",
"type": "@n8n/n8n-nodes-langchain.sentimentAnalysis",
"position": [
60,
140
],
"parameters": {
"options": {
"categories": "Positive, Neutral, Negative",
"systemPromptTemplate": "You are highly intelligent and accurate sentiment analyzer. Analyze the sentiment of the provided text. Categorize it into one of the following: {categories}. Use the provided formatting instructions. Only output the JSON."
},
"inputText": "={{ $json.output.testo }}"
},
"typeVersion": 1
},
{
"id": "79f1b9ea-6297-4735-9c0f-9f28dd65efa0",
"name": "DeepSeek Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
-460,
320
],
"parameters": {
"model": "deepseek-reasoner",
"options": {
"baseURL": "https://api.deepseek.com/v1"
}
},
"credentials": {
"openAiApi": {
"id": "97Cz4cqyiy1RdcQL",
"name": "DeepSeek"
}
},
"typeVersion": 1
},
{
"id": "159cc88e-1dd3-4bba-a3c8-59a9aad14c88",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
40,
320
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "CDX6QM4gLYanh0P4",
"name": "OpenAi account"
}
},
"typeVersion": 1.1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "43c8ee74-159c-4217-9cb4-554c63a3b183",
"connections": {
"If": {
"main": [
[
{
"node": "Get Single review",
"type": "main",
"index": 0
}
]
]
},
"Limit1": {
"main": [
[
{
"node": "Get Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Extract": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"Get rows": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "Limit1",
"type": "main",
"index": 0
}
]
]
},
"Get reviews": {
"main": [
[
{
"node": "Extract",
"type": "main",
"index": 0
}
]
]
},
"Extract review": {
"main": [
[
{
"node": "Information Extractor",
"type": "main",
"index": 0
}
]
]
},
"Set Parameters": {
"main": [
[
{
"node": "Get reviews",
"type": "main",
"index": 0
}
]
]
},
"Get Google Sheets": {
"main": [
[
{
"node": "Get rows",
"type": "main",
"index": 0
}
]
]
},
"Get Single review": {
"main": [
[
{
"node": "Extract review",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Sentiment Analysis",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Sentiment Analysis": {
"main": [
[
{
"node": "Update sheet",
"type": "main",
"index": 0
}
],
[
{
"node": "Update sheet",
"type": "main",
"index": 0
}
],
[
{
"node": "Update sheet",
"type": "main",
"index": 0
}
]
]
},
"DeepSeek Chat Model": {
"ai_languageModel": [
[
{
"node": "Information Extractor",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Information Extractor": {
"main": [
[
{
"node": "Sentiment Analysis",
"type": "main",
"index": 0
}
]
]
},
"When clicking Test workflow": {
"main": [
[
{
"node": "Set Parameters",
"type": "main",
"index": 0
}
]
]
}
}
}

File diff suppressed because it is too large Load Diff