Assistant IA intelligent : Discuter avec les fichiers de Supabase Storage et Google Drive
Ceci est unEngineering, AI, IT Opsworkflow d'automatisation du domainecontenant 62 nœuds.Utilise principalement des nœuds comme If, Set, Wait, Merge, Switch, combinant la technologie d'intelligence artificielle pour une automatisation intelligente. AIintelligentassistant:与Supabase存储etGoogle Drive文件对话
- •Point de terminaison HTTP Webhook (généré automatiquement par n8n)
- •URL et Clé API Supabase
- •Informations d'identification Google Drive API
- •Peut nécessiter les informations d'identification d'authentification de l'API cible
- •Clé API OpenAI
Nœuds utilisés (62)
{
"meta": {
"instanceId": "6a2a7715680b8313f7cb4676321c5baa46680adfb913072f089f2766f42e43bd",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "003915bb-a2e9-42b0-b81f-5bb5bf0c8cb4",
"name": "Get All files",
"type": "n8n-nodes-base.httpRequest",
"position": [
1180,
1280
],
"parameters": {
"url": "=https://<project_id>.supabase.co/storage/v1/object/list/private",
"method": "POST",
"options": {},
"jsonBody": "={\n \"prefix\": \"\",\n \"limit\": 100,\n \"offset\": 0,\n \"sortBy\": {\n \"column\": \"name\",\n \"order\": \"asc\"\n }\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "supabaseApi"
},
"credentials": {
"supabaseApi": {
"id": "t8AQJzvZvrOMDLec",
"name": "Supabase account info@ Demo"
}
},
"typeVersion": 4.2
},
{
"id": "f46e056d-8311-4951-ad38-21759fabdaf7",
"name": "Default Data Loader",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
3500,
1820
],
"parameters": {
"options": {
"metadata": {
"metadataValues": [
{
"name": "=file_id",
"value": "={{ $json.id }}"
}
]
}
},
"jsonData": "={{ $('Merge Text').item.json.text }}",
"jsonMode": "expressionData"
},
"typeVersion": 1
},
{
"id": "3cfdcacb-d0ef-422b-9048-a64e5f0dac66",
"name": "Recursive Character Text Splitter",
"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
"position": [
3520,
1960
],
"parameters": {
"options": {},
"chunkSize": 500,
"chunkOverlap": 200
},
"typeVersion": 1
},
{
"id": "3056ea0a-b788-43c7-a070-f40bd1ad3356",
"name": "Embeddings OpenAI",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
3320,
1800
],
"parameters": {
"model": "text-embedding-3-small",
"options": {}
},
"credentials": {
"openAiApi": {
"id": "fLfRtaXbR0EVD0pl",
"name": "OpenAi account"
}
},
"typeVersion": 1
},
{
"id": "e6ad8067-0468-440d-a322-2a3de8851431",
"name": "Create File record2",
"type": "n8n-nodes-base.supabase",
"position": [
3260,
1620
],
"parameters": {
"tableId": "files",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "name",
"fieldValue": "={{ $('Loop Over Items').item.json.name }}"
},
{
"fieldId": "storage_id",
"fieldValue": "={{ $('Loop Over Items').item.json.id }}"
}
]
}
},
"credentials": {
"supabaseApi": {
"id": "t8AQJzvZvrOMDLec",
"name": "Supabase account info@ Demo"
}
},
"typeVersion": 1
},
{
"id": "53ac0d69-d935-48a0-8fb8-5cc8f591dbb8",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
1500,
1280
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9b14e306-a04d-40f7-bc5b-b8eda8d8f7f2",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ \n !$('Aggregate').item.json.data || \n !Array.isArray($('Aggregate').item.json.data) || \n !$('Aggregate').item.json.data.some(item => \n item.storage_id === $('Loop Over Items').item.json.id \n ) \n}}",
"rightValue": ""
},
{
"id": "c3c0af88-9aea-4539-8948-1b69e601c27c",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.name }}",
"rightValue": ".emptyFolderPlaceholder"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "f57e857a-094f-470c-ad27-9fc29466ab0e",
"name": "Get All Files",
"type": "n8n-nodes-base.supabase",
"position": [
800,
1280
],
"parameters": {
"tableId": "files",
"operation": "getAll"
},
"credentials": {
"supabaseApi": {
"id": "t8AQJzvZvrOMDLec",
"name": "Supabase account info@ Demo"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "4484ca47-6879-43b7-8879-261f409014e1",
"name": "Download",
"type": "n8n-nodes-base.httpRequest",
"position": [
1660,
1280
],
"parameters": {
"url": "=https://<project_id>.supabase.co/storage/v1/object/private/{{ $json.name }}",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "supabaseApi"
},
"credentials": {
"supabaseApi": {
"id": "t8AQJzvZvrOMDLec",
"name": "Supabase account info@ Demo"
}
},
"typeVersion": 4.2
},
{
"id": "f81d2f91-d665-4217-8955-a308ef2b37be",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1340,
1280
],
"parameters": {
"options": {},
"batchSize": "=1"
},
"typeVersion": 3
},
{
"id": "8857a553-37aa-4ac2-ac4d-e5402849cb2e",
"name": "When clicking ‘Test workflow’",
"type": "n8n-nodes-base.manualTrigger",
"disabled": true,
"position": [
620,
1280
],
"parameters": {},
"typeVersion": 1
},
{
"id": "e967af7e-43bd-47cb-8b04-eb431a82c93b",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
1000,
1280
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "8abdb8f6-e31d-48cf-8189-831adf7d4889",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
1420,
300
],
"webhookId": "3c40d311-7996-4ed4-b2fa-c73bea5f4cf5",
"parameters": {
"options": {}
},
"typeVersion": 1.1
},
{
"id": "75cf7f9e-d8f6-4a7a-b464-d152fd025188",
"name": "Insert into Supabase Vectorstore",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
3420,
1620
],
"parameters": {
"mode": "insert",
"options": {
"queryName": "match_documents"
},
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
}
},
"credentials": {
"supabaseApi": {
"id": "t8AQJzvZvrOMDLec",
"name": "Supabase account info@ Demo"
}
},
"typeVersion": 1
},
{
"id": "b3ceb557-53c6-4d19-ac97-c999ba87c7f5",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1120,
1160
],
"parameters": {
"height": 89.3775420487804,
"content": "### Replace Storage name, database ID and credentials."
},
"typeVersion": 1
},
{
"id": "a81fe332-86ea-46aa-b140-ee5745f0b0e0",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
760,
1160
],
"parameters": {
"height": 80,
"content": "### Replace credentials."
},
"typeVersion": 1
},
{
"id": "44070cd1-0f4d-48ea-8ce0-8d59f94133e7",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
3260,
1500
],
"parameters": {
"height": 80,
"content": "### Replace credentials."
},
"typeVersion": 1
},
{
"id": "3fed931d-69de-4c1b-a951-5e49c683f551",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1620,
1160
],
"parameters": {
"height": 89.3775420487804,
"content": "### Replace Storage name, database ID and credentials."
},
"typeVersion": 1
},
{
"id": "d462978c-7ea3-4b92-a940-64756377c461",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
3220,
1940
],
"parameters": {
"height": 80,
"content": "### Replace credentials."
},
"typeVersion": 1
},
{
"id": "6f0a219d-4258-4982-b912-784a850ef308",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2080,
800
],
"parameters": {
"height": 80,
"content": "### Replace credentials."
},
"typeVersion": 1
},
{
"id": "469b3caf-c9a8-4f8b-a745-c672e2b1089f",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
40
],
"parameters": {
"color": 7,
"width": 636.2128494576581,
"height": 497.1532689930921,
"content": "\n## AI Agent To Chat With Files In Supabase Storage\n**Made by [Mark Shcherbakov](https://www.linkedin.com/in/marklowcoding/) from community [5minAI](https://www.skool.com/5minai-2861)**\n\nManually retrieving and analyzing specific information from large document repositories is time-consuming and inefficient. This workflow automates the process by vectorizing documents and enabling AI-powered interactions, making it easy to query and retrieve context-based information from uploaded files.\n\nThe workflow integrates Supabase with an AI-powered chatbot to process, store, and query text and PDF files. The steps include:\n- Fetching and comparing files to avoid duplicate processing.\n- Handling file downloads and extracting content based on the file type.\n- Converting documents into vectorized data for contextual information retrieval.\n- Storing and querying vectorized data from a Supabase vector store.\n\n"
},
"typeVersion": 1
},
{
"id": "cb6664f2-0a05-4abb-818d-d72536b57bac",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
1360,
40
],
"parameters": {
"color": 5,
"width": 1112,
"height": 890,
"content": "## Scenario 2 - AI agent"
},
"typeVersion": 1
},
{
"id": "a825794d-e7f3-41ba-a113-8503ebaf2be7",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
540,
1000
],
"parameters": {
"color": 5,
"width": 3285,
"height": 1139,
"content": "## Scenario 1 - Flow for adding new files from Supabase storage"
},
"typeVersion": 1
},
{
"id": "1d44ef3b-b1d9-481c-8078-2f0d8d586247",
"name": "AI Agent1",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1960,
260
],
"parameters": {
"text": "={{ $('Merge').item.json.message }}",
"options": {
"systemMessage": "You are a helpful assistant.\n\nIMPORTANT Always use knowledge base to respond users.",
"passthroughBinaryImages": false
},
"promptType": "define"
},
"typeVersion": 1.8
},
{
"id": "d1da58a8-e6c0-4a6d-aa53-88c223a97f0a",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1880,
480
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"id": "SphXAX7rlwRLkiox",
"name": "Test club key"
}
},
"typeVersion": 1.2
},
{
"id": "acb2de9b-a9fa-4934-9759-b84b067dc26a",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
2020,
480
],
"parameters": {
"sessionKey": "={{ $('Merge').item.json.session_id }}",
"sessionIdType": "customKey"
},
"typeVersion": 1.3
},
{
"id": "4d91a4e9-e381-485a-847e-50b5dcc43f6b",
"name": "Embeddings OpenAI1",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
2160,
660
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "SphXAX7rlwRLkiox",
"name": "Test club key"
}
},
"typeVersion": 1.2
},
{
"id": "19b5a9a8-7407-4a1c-822f-3000b67da99b",
"name": "Supabase Vector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
2160,
500
],
"parameters": {
"mode": "retrieve-as-tool",
"options": {},
"toolName": "knowledge_base",
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
},
"toolDescription": "Gather facts from knowledge base to respond user."
},
"credentials": {
"supabaseApi": {
"id": "t8AQJzvZvrOMDLec",
"name": "Supabase account info@ Demo"
}
},
"typeVersion": 1.1
},
{
"id": "0b48a55c-9b47-4913-9aec-264d3932c533",
"name": "File Created",
"type": "n8n-nodes-base.googleDriveTrigger",
"position": [
600,
2480
],
"parameters": {
"event": "fileCreated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "list",
"value": "1rFIHlWMlbt0vAh1CWjcmNOmJYk_8jUIb",
"cachedResultUrl": "https://drive.google.com/drive/folders/1rFIHlWMlbt0vAh1CWjcmNOmJYk_8jUIb",
"cachedResultName": "Case - dentist"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "1Irxryx1yQ3upU2i",
"name": "Google Drive account"
}
},
"typeVersion": 1
},
{
"id": "fd7a9260-7d85-4129-bf2d-f7700781091b",
"name": "Download File",
"type": "n8n-nodes-base.googleDrive",
"position": [
1200,
2580
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Set File ID').last().json.file_id }}"
},
"options": {
"googleFileConversion": {
"conversion": {
"docsToFormat": "application/pdf",
"sheetsToFormat": "application/pdf",
"slidesToFormat": "application/pdf",
"drawingsToFormat": "application/pdf"
}
}
},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "1Irxryx1yQ3upU2i",
"name": "Google Drive account"
}
},
"executeOnce": true,
"typeVersion": 3
},
{
"id": "e17a7bc1-6483-439b-acb0-2b13f66466e5",
"name": "File Updated",
"type": "n8n-nodes-base.googleDriveTrigger",
"position": [
620,
2660
],
"parameters": {
"event": "fileUpdated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "list",
"value": "1rFIHlWMlbt0vAh1CWjcmNOmJYk_8jUIb",
"cachedResultUrl": "https://drive.google.com/drive/folders/1rFIHlWMlbt0vAh1CWjcmNOmJYk_8jUIb",
"cachedResultName": "Case - dentist"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "1Irxryx1yQ3upU2i",
"name": "Google Drive account"
}
},
"typeVersion": 1
},
{
"id": "b0e5b639-cf0e-4289-8ce7-96e6fd1e831f",
"name": "Delete Old Doc Rows",
"type": "n8n-nodes-base.supabase",
"position": [
1020,
2580
],
"parameters": {
"tableId": "documents",
"operation": "delete",
"filterType": "string",
"filterString": "=metadata->>drive_file_id=like.*{{ $json.file_id }}*"
},
"credentials": {
"supabaseApi": {
"id": "QBhcokohbJHfQZ9A",
"name": "Supabase club"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "c583b665-b756-4b8c-8150-34f559df9007",
"name": "Set File ID",
"type": "n8n-nodes-base.set",
"position": [
860,
2580
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "10646eae-ae46-4327-a4dc-9987c2d76173",
"name": "file_id",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "7d0b3a5e-9dfa-46d3-bf16-f6fc1d44f242",
"name": "extension",
"type": "string",
"value": "={{ $json.fileExtension }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "558473fe-cc06-41d8-ab06-cc6c03a8c40e",
"name": "Create File record1",
"type": "n8n-nodes-base.supabase",
"position": [
2380,
2780
],
"parameters": {
"tableId": "files",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "name",
"fieldValue": "={{ $('Download File').item.binary.data.fileName }}"
},
{
"fieldId": "google_drive_id",
"fieldValue": "={{ $('Set File ID').item.json.file_id }}"
}
]
}
},
"credentials": {
"supabaseApi": {
"id": "t8AQJzvZvrOMDLec",
"name": "Supabase account info@ Demo"
}
},
"typeVersion": 1
},
{
"id": "87e490c4-f9cb-4821-a234-a9c9d2c93836",
"name": "Default Data Loader1",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
2640,
2980
],
"parameters": {
"options": {
"metadata": {
"metadataValues": [
{
"name": "=file_id",
"value": "={{ $json.id }}"
},
{
"name": "drive_file_id",
"value": "={{ $('Set File ID').item.json.file_id }}"
}
]
}
},
"jsonData": "={{ $('Set Text3').item.json.text }}",
"jsonMode": "expressionData"
},
"typeVersion": 1
},
{
"id": "373efd3c-f7dd-4efc-a268-ed05d8b2e309",
"name": "Embeddings OpenAI3",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
2480,
2960
],
"parameters": {
"model": "text-embedding-3-small",
"options": {}
},
"credentials": {
"openAiApi": {
"id": "fLfRtaXbR0EVD0pl",
"name": "OpenAi account"
}
},
"typeVersion": 1
},
{
"id": "17daf2dd-1d4c-498e-8404-7cc371f81894",
"name": "Recursive Character Text Splitter1",
"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
"position": [
2660,
3180
],
"parameters": {
"options": {},
"chunkSize": 500,
"chunkOverlap": 200
},
"typeVersion": 1
},
{
"id": "afcfc728-9798-4703-998d-edc535eb859e",
"name": "Insert into Supabase Vectorstore1",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
2580,
2780
],
"parameters": {
"mode": "insert",
"options": {
"queryName": "match_documents"
},
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
}
},
"credentials": {
"supabaseApi": {
"id": "t8AQJzvZvrOMDLec",
"name": "Supabase account info@ Demo"
}
},
"typeVersion": 1
},
{
"id": "78e7d15c-5797-488c-b869-bb887878e930",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
540,
2240
],
"parameters": {
"color": 5,
"width": 2465,
"height": 1139,
"content": "## Scenario 3 - Flow for adding new files from Supabase storage"
},
"typeVersion": 1
},
{
"id": "f572511d-6374-4b0b-8907-9f6c82179feb",
"name": "Edit Fields",
"type": "n8n-nodes-base.set",
"position": [
1600,
300
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "ad3055e5-41eb-4e00-9f55-dbcde47a03c7",
"name": "session_id",
"type": "string",
"value": "={{ $('When chat message received').item.json.sessionId }}"
},
{
"id": "56126e31-5fe0-4a9c-b9c9-d62fcb8bd469",
"name": "message",
"type": "string",
"value": "={{ $('When chat message received').item.json.chatInput }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "be2de117-410c-49c2-b95c-45b4a0e036d6",
"name": "Edit Fields1",
"type": "n8n-nodes-base.set",
"position": [
1600,
140
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "5e5fbeb0-d866-40fe-8c1b-66b946bd1cec",
"name": "session_id",
"type": "string",
"value": "={{ $('Webhook').item.json.body.session_id }}"
},
{
"id": "28ec27a5-f814-435c-a5bf-df92160eee3e",
"name": "message",
"type": "string",
"value": "={{ $('Webhook').item.json.body.message }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "ce8790a1-55a5-4583-8301-03bbde363ee2",
"name": "Upload File",
"type": "n8n-nodes-base.httpRequest",
"position": [
2040,
1280
],
"parameters": {
"url": "https://api.cloud.llamaindex.ai/api/parsing/upload",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "file",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
},
{
"name": "do_not_cache",
"value": "=true"
}
]
},
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{
"name": "accept",
"value": "application/json"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"id": "AkhbJSroTy15x6o9",
"name": "Llama parse bqman"
}
},
"typeVersion": 4.2
},
{
"id": "10b8cf52-4301-40a2-a27d-9952f1d3bcda",
"name": "Get Processing Status",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
2240,
1280
],
"parameters": {
"url": "=https://api.cloud.llamaindex.ai/api/parsing/job/{{ $json.id }}",
"options": {},
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{
"name": "accept",
"value": "application/json"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"id": "AkhbJSroTy15x6o9",
"name": "Llama parse bqman"
}
},
"typeVersion": 4.2
},
{
"id": "c0fc7854-1d04-492d-9541-389356333efd",
"name": "Wait to stay within service limits",
"type": "n8n-nodes-base.wait",
"position": [
2660,
1040
],
"webhookId": "17a96ed6-b5ff-47bb-a8a2-39c1eb40185a",
"parameters": {
"amount": 7
},
"typeVersion": 1.1
},
{
"id": "971b40d2-a320-4815-9ccc-27de52b58bbd",
"name": "Is Job Ready?",
"type": "n8n-nodes-base.switch",
"position": [
2420,
1280
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "PENDING",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0fa97d86-432a-409a-917e-5f1a002b1ab9",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "PENDING"
}
]
},
"renameOutput": true
},
{
"outputKey": "ERROR",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "e6058aa0-a3e2-4ce3-9bed-6ff41a5be052",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "ERROR"
}
]
},
"renameOutput": true
},
{
"outputKey": "CANCELED",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "ceb6338f-4261-40ac-be11-91f61c7302ba",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "CANCELED"
}
]
},
"renameOutput": true
},
{
"outputKey": "SUCCESS",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "300fce8c-b19a-4d0c-86e8-f62853c70ce2",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "SUCCESS"
}
]
},
"renameOutput": true
}
]
},
"options": {
"allMatchingOutputs": true
}
},
"typeVersion": 3
},
{
"id": "c8f65cc5-e67a-47ae-b43a-fc065fb4900e",
"name": "Stop and Error",
"type": "n8n-nodes-base.stopAndError",
"position": [
2660,
1300
],
"parameters": {
"errorMessage": "Problem with Llamaparser. Error during parsing."
},
"typeVersion": 1
},
{
"id": "90658f0a-7236-493d-8dd0-fdad64196753",
"name": "Get Parsed Data",
"type": "n8n-nodes-base.httpRequest",
"position": [
2660,
1480
],
"parameters": {
"url": "=https://api.cloud.llamaindex.ai/api/parsing/job/{{ $json.id }}/result/markdown",
"options": {
"redirect": {
"redirect": {}
}
},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "AkhbJSroTy15x6o9",
"name": "Llama parse bqman"
}
},
"typeVersion": 4.2
},
{
"id": "810aad96-7677-4c27-b3b2-25106b70083a",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
2060,
1460
],
"parameters": {
"width": 280,
"height": 80,
"content": "### Add Llamaparse Header auth\nAuthorization: Bearer <api_key>"
},
"typeVersion": 1
},
{
"id": "a0fd62b8-219e-4eb7-b274-1344b0042fac",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
1800,
260
],
"parameters": {},
"typeVersion": 3.1
},
{
"id": "e5356266-5e4a-41a2-8151-95f994435560",
"name": "If1",
"type": "n8n-nodes-base.if",
"position": [
1820,
1280
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f05d708d-f36e-4c6d-8753-81a61ae42546",
"operator": {
"type": "string",
"operation": "notExists",
"singleValue": true
},
"leftValue": "={{ $json.data }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "c04fa3f9-74c6-4c7c-ae2a-46a797db0e55",
"name": "Set Text",
"type": "n8n-nodes-base.set",
"position": [
2060,
1600
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "e9bbecd9-3d40-4a6a-9401-94daab15cde0",
"name": "text",
"type": "string",
"value": "={{ $('If1').item.json.data }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "2f41ef18-6229-4d3c-9a3c-8b02ec3c60b2",
"name": "Set Text1",
"type": "n8n-nodes-base.set",
"position": [
2840,
1480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "e9bbecd9-3d40-4a6a-9401-94daab15cde0",
"name": "text",
"type": "string",
"value": "={{ $('Get Parsed Data').item.json.markdown }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "9c92b25b-7762-4465-878f-6568073ba521",
"name": "Merge Text",
"type": "n8n-nodes-base.merge",
"position": [
3060,
1620
],
"parameters": {},
"typeVersion": 3.1
},
{
"id": "4a523ad6-d74d-4207-8347-facc7f313fdd",
"name": "Upload File1",
"type": "n8n-nodes-base.httpRequest",
"position": [
1380,
2580
],
"parameters": {
"url": "https://api.cloud.llamaindex.ai/api/parsing/upload",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "file",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
},
{
"name": "do_not_cache",
"value": "=true"
}
]
},
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{
"name": "accept",
"value": "application/json"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"id": "AkhbJSroTy15x6o9",
"name": "Llama parse bqman"
}
},
"typeVersion": 4.2
},
{
"id": "c0a43e5e-ec2b-49f5-bbc0-cef914c68c4c",
"name": "Get Processing Status1",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
1580,
2580
],
"parameters": {
"url": "=https://api.cloud.llamaindex.ai/api/parsing/job/{{ $json.id }}",
"options": {},
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{
"name": "accept",
"value": "application/json"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"id": "AkhbJSroTy15x6o9",
"name": "Llama parse bqman"
}
},
"typeVersion": 4.2
},
{
"id": "68cc70a4-dba0-4ec9-8506-88bb20b37e87",
"name": "Wait to stay within service limits1",
"type": "n8n-nodes-base.wait",
"position": [
2000,
2340
],
"webhookId": "17a96ed6-b5ff-47bb-a8a2-39c1eb40185a",
"parameters": {
"amount": 7
},
"typeVersion": 1.1
},
{
"id": "aef3b805-166e-47a8-a81c-900f999ae045",
"name": "Is Job Ready?1",
"type": "n8n-nodes-base.switch",
"position": [
1760,
2580
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "PENDING",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0fa97d86-432a-409a-917e-5f1a002b1ab9",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "PENDING"
}
]
},
"renameOutput": true
},
{
"outputKey": "ERROR",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "e6058aa0-a3e2-4ce3-9bed-6ff41a5be052",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "ERROR"
}
]
},
"renameOutput": true
},
{
"outputKey": "CANCELED",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "ceb6338f-4261-40ac-be11-91f61c7302ba",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "CANCELED"
}
]
},
"renameOutput": true
},
{
"outputKey": "SUCCESS",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "300fce8c-b19a-4d0c-86e8-f62853c70ce2",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "SUCCESS"
}
]
},
"renameOutput": true
}
]
},
"options": {
"allMatchingOutputs": true
}
},
"typeVersion": 3
},
{
"id": "5233be31-2ecf-4ddd-96e2-b0fd614f535f",
"name": "Stop and Error1",
"type": "n8n-nodes-base.stopAndError",
"position": [
2000,
2600
],
"parameters": {
"errorMessage": "Problem with Llamaparser. Error during parsing."
},
"typeVersion": 1
},
{
"id": "09283faa-4ab9-4d59-a610-3491d7f2daf8",
"name": "Get Parsed Data1",
"type": "n8n-nodes-base.httpRequest",
"position": [
2000,
2780
],
"parameters": {
"url": "=https://api.cloud.llamaindex.ai/api/parsing/job/{{ $json.id }}/result/markdown",
"options": {
"redirect": {
"redirect": {}
}
},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "AkhbJSroTy15x6o9",
"name": "Llama parse bqman"
}
},
"typeVersion": 4.2
},
{
"id": "5ef6959d-1eb4-49cd-9b19-3b0e1aaa0eb7",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
1400,
2760
],
"parameters": {
"width": 280,
"height": 80,
"content": "### Add Llamaparse Header auth\nAuthorization: Bearer <api_key>"
},
"typeVersion": 1
},
{
"id": "18fd1d0f-664e-4584-8154-794ca8aad768",
"name": "Set Text3",
"type": "n8n-nodes-base.set",
"position": [
2180,
2780
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "e9bbecd9-3d40-4a6a-9401-94daab15cde0",
"name": "text",
"type": "string",
"value": "={{ $('Get Parsed Data1').item.json.markdown }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "337b8593-8f5a-47b2-8b75-f5b3b4195fe8",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
1420,
140
],
"webhookId": "05979e87-19bc-4e8b-adbb-7e04808f8b21",
"parameters": {
"path": "05979e87-19bc-4e8b-adbb-7e04808f8b21",
"options": {},
"httpMethod": "POST",
"responseMode": "lastNode"
},
"typeVersion": 2
},
{
"id": "7911c133-f998-4efd-a9c8-9c52c8e545c4",
"name": "Sticky Note14",
"type": "n8n-nodes-base.stickyNote",
"position": [
2380,
2660
],
"parameters": {
"width": 480,
"height": 80,
"content": "### Replace credentials."
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"53ac0d69-d935-48a0-8fb8-5cc8f591dbb8": {
"main": [
[
{
"node": "4484ca47-6879-43b7-8879-261f409014e1",
"type": "main",
"index": 0
}
],
[
{
"node": "f81d2f91-d665-4217-8955-a308ef2b37be",
"type": "main",
"index": 0
}
]
]
},
"e5356266-5e4a-41a2-8151-95f994435560": {
"main": [
[
{
"node": "ce8790a1-55a5-4583-8301-03bbde363ee2",
"type": "main",
"index": 0
}
],
[
{
"node": "c04fa3f9-74c6-4c7c-ae2a-46a797db0e55",
"type": "main",
"index": 0
}
]
]
},
"a0fd62b8-219e-4eb7-b274-1344b0042fac": {
"main": [
[
{
"node": "1d44ef3b-b1d9-481c-8078-2f0d8d586247",
"type": "main",
"index": 0
}
]
]
},
"337b8593-8f5a-47b2-8b75-f5b3b4195fe8": {
"main": [
[
{
"node": "be2de117-410c-49c2-b95c-45b4a0e036d6",
"type": "main",
"index": 0
}
]
]
},
"4484ca47-6879-43b7-8879-261f409014e1": {
"main": [
[
{
"node": "e5356266-5e4a-41a2-8151-95f994435560",
"type": "main",
"index": 0
}
]
]
},
"c04fa3f9-74c6-4c7c-ae2a-46a797db0e55": {
"main": [
[
{
"node": "9c92b25b-7762-4465-878f-6568073ba521",
"type": "main",
"index": 1
}
]
]
},
"e967af7e-43bd-47cb-8b04-eb431a82c93b": {
"main": [
[
{
"node": "003915bb-a2e9-42b0-b81f-5bb5bf0c8cb4",
"type": "main",
"index": 0
}
]
]
},
"2f41ef18-6229-4d3c-9a3c-8b02ec3c60b2": {
"main": [
[
{
"node": "9c92b25b-7762-4465-878f-6568073ba521",
"type": "main",
"index": 0
}
]
]
},
"18fd1d0f-664e-4584-8154-794ca8aad768": {
"main": [
[
{
"node": "558473fe-cc06-41d8-ab06-cc6c03a8c40e",
"type": "main",
"index": 0
}
]
]
},
"9c92b25b-7762-4465-878f-6568073ba521": {
"main": [
[
{
"node": "e6ad8067-0468-440d-a322-2a3de8851431",
"type": "main",
"index": 0
}
]
]
},
"f572511d-6374-4b0b-8907-9f6c82179feb": {
"main": [
[
{
"node": "a0fd62b8-219e-4eb7-b274-1344b0042fac",
"type": "main",
"index": 1
}
]
]
},
"c583b665-b756-4b8c-8150-34f559df9007": {
"main": [
[
{
"node": "b0e5b639-cf0e-4289-8ce7-96e6fd1e831f",
"type": "main",
"index": 0
}
]
]
},
"ce8790a1-55a5-4583-8301-03bbde363ee2": {
"main": [
[
{
"node": "10b8cf52-4301-40a2-a27d-9952f1d3bcda",
"type": "main",
"index": 0
}
]
]
},
"be2de117-410c-49c2-b95c-45b4a0e036d6": {
"main": [
[
{
"node": "a0fd62b8-219e-4eb7-b274-1344b0042fac",
"type": "main",
"index": 0
}
]
]
},
"0b48a55c-9b47-4913-9aec-264d3932c533": {
"main": [
[
{
"node": "c583b665-b756-4b8c-8150-34f559df9007",
"type": "main",
"index": 0
}
]
]
},
"e17a7bc1-6483-439b-acb0-2b13f66466e5": {
"main": [
[
{
"node": "c583b665-b756-4b8c-8150-34f559df9007",
"type": "main",
"index": 0
}
]
]
},
"4a523ad6-d74d-4207-8347-facc7f313fdd": {
"main": [
[
{
"node": "c0a43e5e-ec2b-49f5-bbc0-cef914c68c4c",
"type": "main",
"index": 0
}
]
]
},
"fd7a9260-7d85-4129-bf2d-f7700781091b": {
"main": [
[
{
"node": "4a523ad6-d74d-4207-8347-facc7f313fdd",
"type": "main",
"index": 0
}
]
]
},
"f57e857a-094f-470c-ad27-9fc29466ab0e": {
"main": [
[
{
"node": "e967af7e-43bd-47cb-8b04-eb431a82c93b",
"type": "main",
"index": 0
}
]
]
},
"003915bb-a2e9-42b0-b81f-5bb5bf0c8cb4": {
"main": [
[
{
"node": "f81d2f91-d665-4217-8955-a308ef2b37be",
"type": "main",
"index": 0
}
]
]
},
"971b40d2-a320-4815-9ccc-27de52b58bbd": {
"main": [
[
{
"node": "c0fc7854-1d04-492d-9541-389356333efd",
"type": "main",
"index": 0
}
],
[
{
"node": "c8f65cc5-e67a-47ae-b43a-fc065fb4900e",
"type": "main",
"index": 0
}
],
[
{
"node": "c8f65cc5-e67a-47ae-b43a-fc065fb4900e",
"type": "main",
"index": 0
}
],
[
{
"node": "90658f0a-7236-493d-8dd0-fdad64196753",
"type": "main",
"index": 0
}
]
]
},
"acb2de9b-a9fa-4934-9759-b84b067dc26a": {
"ai_memory": [
[
{
"node": "1d44ef3b-b1d9-481c-8078-2f0d8d586247",
"type": "ai_memory",
"index": 0
}
]
]
},
"aef3b805-166e-47a8-a81c-900f999ae045": {
"main": [
[
{
"node": "68cc70a4-dba0-4ec9-8506-88bb20b37e87",
"type": "main",
"index": 0
}
],
[
{
"node": "5233be31-2ecf-4ddd-96e2-b0fd614f535f",
"type": "main",
"index": 0
}
],
[
{
"node": "5233be31-2ecf-4ddd-96e2-b0fd614f535f",
"type": "main",
"index": 0
}
],
[
{
"node": "09283faa-4ab9-4d59-a610-3491d7f2daf8",
"type": "main",
"index": 0
}
]
]
},
"90658f0a-7236-493d-8dd0-fdad64196753": {
"main": [
[
{
"node": "2f41ef18-6229-4d3c-9a3c-8b02ec3c60b2",
"type": "main",
"index": 0
}
]
]
},
"f81d2f91-d665-4217-8955-a308ef2b37be": {
"main": [
[],
[
{
"node": "53ac0d69-d935-48a0-8fb8-5cc8f591dbb8",
"type": "main",
"index": 0
}
]
]
},
"09283faa-4ab9-4d59-a610-3491d7f2daf8": {
"main": [
[
{
"node": "18fd1d0f-664e-4584-8154-794ca8aad768",
"type": "main",
"index": 0
}
]
]
},
"3056ea0a-b788-43c7-a070-f40bd1ad3356": {
"ai_embedding": [
[
{
"node": "75cf7f9e-d8f6-4a7a-b464-d152fd025188",
"type": "ai_embedding",
"index": 0
}
]
]
},
"d1da58a8-e6c0-4a6d-aa53-88c223a97f0a": {
"ai_languageModel": [
[
{
"node": "1d44ef3b-b1d9-481c-8078-2f0d8d586247",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"4d91a4e9-e381-485a-847e-50b5dcc43f6b": {
"ai_embedding": [
[
{
"node": "19b5a9a8-7407-4a1c-822f-3000b67da99b",
"type": "ai_embedding",
"index": 0
}
]
]
},
"373efd3c-f7dd-4efc-a268-ed05d8b2e309": {
"ai_embedding": [
[
{
"node": "afcfc728-9798-4703-998d-edc535eb859e",
"type": "ai_embedding",
"index": 0
}
]
]
},
"558473fe-cc06-41d8-ab06-cc6c03a8c40e": {
"main": [
[
{
"node": "afcfc728-9798-4703-998d-edc535eb859e",
"type": "main",
"index": 0
}
]
]
},
"e6ad8067-0468-440d-a322-2a3de8851431": {
"main": [
[
{
"node": "75cf7f9e-d8f6-4a7a-b464-d152fd025188",
"type": "main",
"index": 0
}
]
]
},
"f46e056d-8311-4951-ad38-21759fabdaf7": {
"ai_document": [
[
{
"node": "75cf7f9e-d8f6-4a7a-b464-d152fd025188",
"type": "ai_document",
"index": 0
}
]
]
},
"b0e5b639-cf0e-4289-8ce7-96e6fd1e831f": {
"main": [
[
{
"node": "fd7a9260-7d85-4129-bf2d-f7700781091b",
"type": "main",
"index": 0
}
]
]
},
"87e490c4-f9cb-4821-a234-a9c9d2c93836": {
"ai_document": [
[
{
"node": "afcfc728-9798-4703-998d-edc535eb859e",
"type": "ai_document",
"index": 0
}
]
]
},
"10b8cf52-4301-40a2-a27d-9952f1d3bcda": {
"main": [
[
{
"node": "971b40d2-a320-4815-9ccc-27de52b58bbd",
"type": "main",
"index": 0
}
],
[
{
"node": "c8f65cc5-e67a-47ae-b43a-fc065fb4900e",
"type": "main",
"index": 0
}
]
]
},
"19b5a9a8-7407-4a1c-822f-3000b67da99b": {
"ai_tool": [
[
{
"node": "1d44ef3b-b1d9-481c-8078-2f0d8d586247",
"type": "ai_tool",
"index": 0
}
]
]
},
"c0a43e5e-ec2b-49f5-bbc0-cef914c68c4c": {
"main": [
[
{
"node": "aef3b805-166e-47a8-a81c-900f999ae045",
"type": "main",
"index": 0
}
],
[
{
"node": "5233be31-2ecf-4ddd-96e2-b0fd614f535f",
"type": "main",
"index": 0
}
]
]
},
"8abdb8f6-e31d-48cf-8189-831adf7d4889": {
"main": [
[
{
"node": "f572511d-6374-4b0b-8907-9f6c82179feb",
"type": "main",
"index": 0
}
]
]
},
"75cf7f9e-d8f6-4a7a-b464-d152fd025188": {
"main": [
[
{
"node": "f81d2f91-d665-4217-8955-a308ef2b37be",
"type": "main",
"index": 0
}
]
]
},
"3cfdcacb-d0ef-422b-9048-a64e5f0dac66": {
"ai_textSplitter": [
[
{
"node": "f46e056d-8311-4951-ad38-21759fabdaf7",
"type": "ai_textSplitter",
"index": 0
}
]
]
},
"8857a553-37aa-4ac2-ac4d-e5402849cb2e": {
"main": [
[
{
"node": "f57e857a-094f-470c-ad27-9fc29466ab0e",
"type": "main",
"index": 0
}
]
]
},
"17daf2dd-1d4c-498e-8404-7cc371f81894": {
"ai_textSplitter": [
[
{
"node": "87e490c4-f9cb-4821-a234-a9c9d2c93836",
"type": "ai_textSplitter",
"index": 0
}
]
]
},
"c0fc7854-1d04-492d-9541-389356333efd": {
"main": [
[
{
"node": "10b8cf52-4301-40a2-a27d-9952f1d3bcda",
"type": "main",
"index": 0
}
]
]
},
"68cc70a4-dba0-4ec9-8506-88bb20b37e87": {
"main": [
[
{
"node": "c0a43e5e-ec2b-49f5-bbc0-cef914c68c4c",
"type": "main",
"index": 0
}
]
]
}
}
}Comment utiliser ce workflow ?
Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.
Dans quelles scénarios ce workflow est-il adapté ?
Avancé - Ingénierie, Intelligence Artificielle, Opérations IT
Est-ce payant ?
Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.
Workflows recommandés
Mark Shcherbakov
@lowcodingdevI am a business analyst with a development background, dedicated to helping small businesses and entrepreneurs leverage cloud services for increased efficiency. My expertise lies in automating manual workflows, integrating data from multiple cloud service providers, creating insightful dashboards, and building custom CRM systems. https://www.linkedin.com/in/marklowcoding/
Partager ce workflow