feat: add folder support for workflows (fixes #70)
This commit is contained in:
@@ -0,0 +1,647 @@
|
||||
{
|
||||
"meta": {
|
||||
"instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"id": "9681490a-68f1-4c6a-86ea-bf2331c3125d",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"position": [
|
||||
-600,
|
||||
1040
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "f665f0c6-7694-456f-b877-5f8d69b9f503",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-680,
|
||||
920
|
||||
],
|
||||
"parameters": {
|
||||
"width": 715.3278290432247,
|
||||
"height": 315.32782904322477,
|
||||
"content": "## Get and prepare Dummy Data"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "79a9ece6-daa5-4cc0-bfb8-5cf8c9e81296",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
340,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"width": 520.9323109877616,
|
||||
"height": 577.5426854600692,
|
||||
"content": "## Let GPT do the heavy work\n\nFor the prompt we follow the one-shot'ish principle. Also I've decided to **_NOT_** give the AI the personal data. Keeps it simpler regarding data privacy.\n\nThe AI-Chain will generate a **Headline** and the **Text** for the Email and even **decides** if we should send the user a **Coupon**."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "51e1bc15-0b9e-4d53-9b99-0ec8ed5e00f8",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
2240,
|
||||
620
|
||||
],
|
||||
"parameters": {
|
||||
"width": 358,
|
||||
"height": 324,
|
||||
"content": "## HTML Email-Template without Coupon"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "ee29375a-77fe-4d13-a453-c8b62f0884a7",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1100,
|
||||
880
|
||||
],
|
||||
"parameters": {
|
||||
"width": 447,
|
||||
"height": 465,
|
||||
"content": "## Make sure we have what we need\nWe do not want to sent empty messages to our customers"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "37e09224-3649-43e0-a40f-f8177aa93cda",
|
||||
"name": "Sticky Note4",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
2240,
|
||||
1140
|
||||
],
|
||||
"parameters": {
|
||||
"width": 369.917435648372,
|
||||
"height": 330.56011245057107,
|
||||
"content": "## HTML Email-Template with Coupon"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "5147fe48-606d-4dad-9977-2713f40fc8e6",
|
||||
"name": "Sticky Note5",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1880,
|
||||
1140
|
||||
],
|
||||
"parameters": {
|
||||
"width": 319.84249777513367,
|
||||
"height": 330.6656654860422,
|
||||
"content": "## Mocked: Fake a Coupon Code\nFor a real life scenario add the automated coupon generation here"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "6a3ee9b0-540e-4242-a6ac-535e2b23ea3a",
|
||||
"name": "Sticky Note6",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-680,
|
||||
300
|
||||
],
|
||||
"parameters": {
|
||||
"width": 534.1315466553021,
|
||||
"height": 566.556517486655,
|
||||
"content": "# Documentation\n\nThis Workflow is for the n8n AI / Langchain Competition.\n\nIt solves the Problem: Personalizing marketing emails based on customer purchase history.\n\nI've found it a bit ambiguous and decided to go the \"Convert unhappy customers with a Coupon\"-Route.\n\nSo this workflow utilizes the new LangChain Node for generating personalized E-Mail campaigns and decide if the user might need a coupon to be satisfied. Classic Rebound stuff. \n\nThere is also a Node \"Some Options...\" which can be adjusted to quickly change the direction this Campaign should go.\n\nAdditionally we use n8n to generate the HTML Mails by two different Templates. One with simple text and another for that Coupon handling.\n\n\nEnjoy the Workflow! ❤️ \nhttps://let-the-work-flow.com\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "01cf3e60-c280-46c1-9971-ccf63a28ab9a",
|
||||
"name": "Sticky Note7",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
3040,
|
||||
760
|
||||
],
|
||||
"parameters": {
|
||||
"width": 326.9476248855971,
|
||||
"height": 414.15459581943776,
|
||||
"content": "## Send the Email to the Customer\n\nAlthough it's cool that n8n allows sending emails via SMPT I would recommend to stick to your newsletter tool for that to keep track of opt-outs and stuff."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "6c458bf6-ea7b-43b5-bc65-d9ae68542a8c",
|
||||
"name": "Extract from File",
|
||||
"type": "n8n-nodes-base.extractFromFile",
|
||||
"position": [
|
||||
-160,
|
||||
1040
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"operation": "xls"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "780dd707-4493-4679-9064-acc3c59011f8",
|
||||
"name": "Some Options for the Campaign",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
140,
|
||||
1040
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "8ef766db-4ad1-43c7-b621-8ea3ed0a44b2",
|
||||
"name": "Campaign Target",
|
||||
"type": "string",
|
||||
"value": "Engage the Customer"
|
||||
},
|
||||
{
|
||||
"id": "9f9ce88a-a24a-4a27-8b25-25ee85e730d6",
|
||||
"name": "Flavour",
|
||||
"type": "string",
|
||||
"value": "be friendly and witty but also cool and direct. Critique is valuable and embrace the feedback."
|
||||
}
|
||||
]
|
||||
},
|
||||
"includeOtherFields": true
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "3b152bdc-acb8-4f37-8b91-1ab02c0e9532",
|
||||
"name": "Information Extractor",
|
||||
"type": "@n8n/n8n-nodes-langchain.informationExtractor",
|
||||
"position": [
|
||||
480,
|
||||
700
|
||||
],
|
||||
"parameters": {
|
||||
"text": "=Item Purchased: {{ $json['Item Purchased'] }} \nFeedback: {{ $json.Feedback }}\nShould we send a coupon to make the customer happy? Yes/No",
|
||||
"options": {
|
||||
"systemPromptTemplate": "=Determine the sentiment of the given product feedback. Then generate a Headline and Text without salutation or any greeting for a personalized Email Campagin after a User gave a product review. If the user seems not happy, tell them that you have a Coupon for them. The User finds the Coupon Code below this E-mail. \nThe target of the campagin: {{ $json['Campaign Target'] }}.\nRemember: {{ $json['Flavour'] }}. Avoid any greeting.\n"
|
||||
},
|
||||
"schemaType": "manual",
|
||||
"inputSchema": "{\n \"type\": \"object\",\n \"required\": [\"Headline\",\"Body\",\"SendCoupon\"],\n \"properties\": {\n \"Headline\": {\n \"type\": \"string\"\n },\n \"Body\": {\n \"type\": \"string\"\n },\n \"SendCoupon\": {\n \"type\": \"boolean\"\n }\n }\n}"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "f597a54e-27e9-46e8-b9d5-46dd54406803",
|
||||
"name": "OpenAI Chat Model1",
|
||||
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
|
||||
"position": [
|
||||
480,
|
||||
880
|
||||
],
|
||||
"parameters": {
|
||||
"model": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": "gpt-4o-mini"
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"credentials": {
|
||||
"openAiApi": {
|
||||
"id": "8gccIjcuf3gvaoEr",
|
||||
"name": "OpenAi account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "716e4281-cf18-4cc7-b5ed-4de0308bf9aa",
|
||||
"name": "AI did fail us1",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
1380,
|
||||
1180
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "Unexpected Langchain Output"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "1dc51ad5-e605-4cad-9a5b-3b20eabd9797",
|
||||
"name": "Fake coupon",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
1980,
|
||||
1280
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "73989d0e-667f-4227-ab41-4eb1e8c1c10e",
|
||||
"name": "Coupon",
|
||||
"type": "string",
|
||||
"value": "F4k3ItT1llY0uM4k3It"
|
||||
},
|
||||
{
|
||||
"id": "4d86d8c8-1be3-40b0-b4fd-09f9ffc24386",
|
||||
"name": "Coupon Value",
|
||||
"type": "string",
|
||||
"value": "20% of any purchase"
|
||||
},
|
||||
{
|
||||
"id": "f73b8a70-5bf6-45c2-8061-d10f95b199a8",
|
||||
"name": "Coupon Terms",
|
||||
"type": "string",
|
||||
"value": "=Valid until {{ $today.plus({days: 14}).format(\"d. MMM. y\") }} | minimum purchase amount: 20$ "
|
||||
}
|
||||
]
|
||||
},
|
||||
"includeOtherFields": true
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "dfa6b376-dd66-40f1-8626-0f3f04e4c4bd",
|
||||
"name": "Download dummy data",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
-380,
|
||||
1040
|
||||
],
|
||||
"parameters": {
|
||||
"url": "https://let-the-work-flow.com/dummy/n8n-contest-merch.xlsx",
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "a95ce7c4-c592-40c7-9dfa-db0e37d5b71f",
|
||||
"name": "AI Output + Prev Data",
|
||||
"type": "n8n-nodes-base.merge",
|
||||
"position": [
|
||||
940,
|
||||
1040
|
||||
],
|
||||
"parameters": {
|
||||
"mode": "combine",
|
||||
"options": {},
|
||||
"combineBy": "combineByPosition"
|
||||
},
|
||||
"typeVersion": 3
|
||||
},
|
||||
{
|
||||
"id": "bb0474a1-425c-4a02-a13e-385272091189",
|
||||
"name": "Is the result valid?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
1160,
|
||||
1040
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "9b4ced26-dd86-4ae4-8f69-6177ec42c827",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "notEmpty",
|
||||
"singleValue": true
|
||||
},
|
||||
"leftValue": "Headline",
|
||||
"rightValue": ""
|
||||
},
|
||||
{
|
||||
"id": "7723102c-43d2-48df-82f6-5bb45ddf615c",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "notEmpty",
|
||||
"singleValue": true
|
||||
},
|
||||
"leftValue": "Body",
|
||||
"rightValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "b39e0b98-6824-4265-94a0-fe12154f2ad4",
|
||||
"name": "Coupon them or not to Coupon them",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
1620,
|
||||
1040
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "967f37a1-a600-46a2-82cf-f340dd3c7a96",
|
||||
"operator": {
|
||||
"type": "boolean",
|
||||
"operation": "true",
|
||||
"singleValue": true
|
||||
},
|
||||
"leftValue": "={{ $json.SendCoupon }}",
|
||||
"rightValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "13c4426f-f522-4127-b899-7e6397e18182",
|
||||
"name": "Html Template for our Email",
|
||||
"type": "n8n-nodes-base.html",
|
||||
"position": [
|
||||
2360,
|
||||
740
|
||||
],
|
||||
"parameters": {
|
||||
"html": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\" />\n <title>{{ $json['Headline'] }}</title>\n</head>\n<body>\n <div class=\"container\">\n <img class=\"logo\" src=\"https://img.logoipsum.com/264.svg\"/>\n <h1>Hey {{ $json['Custome Name'] ? $json['Custome Name']+', ' : '!' }}</h1>\n <p>{{ $json['Body'] }}</p>\n \n <div class=\"footer\">\n <p>\n Definitely not a real company Lmt.<br>\n Also not a real street 123<br>\n Unreal Town\n </p> \n</div> \n </div>\n \n \n</body>\n</html>\n\n<style>\n.logo {\n margin-top: 20px;\n }\n.container {\n background-color: #ffffff;\n font-family: sans-serif;\n padding: 16px;\n border-radius: 8px;\n}\n\nh1 {\n color: #ff6d5a;\n font-size: 24px;\n font-weight: bold;\n margin-top: 30px;\n}\n\np {\n color: #606060;\n line-height: 1.6;\n}\n\nh2 {\n color: #909399;\n font-size: 20px;\n font-weight: bold;\n padding: 8px;\n}\n\n.footer {\n margin-top: 30px;\n}\n\n.footer > p {\n font-size: 14px;\n color: #ccc;\n }\n\n</style>"
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "71e36c09-6e24-4eb2-9b1a-4fb3bb4b4536",
|
||||
"name": "The composed E-Mail + Prev Data",
|
||||
"type": "n8n-nodes-base.merge",
|
||||
"position": [
|
||||
2740,
|
||||
860
|
||||
],
|
||||
"parameters": {
|
||||
"mode": "combine",
|
||||
"options": {},
|
||||
"combineBy": "combineByPosition"
|
||||
},
|
||||
"typeVersion": 3
|
||||
},
|
||||
{
|
||||
"id": "a2b6ec8e-1bcf-4216-b9b6-476c0d82f706",
|
||||
"name": "Html Template for our Email with a Coupon",
|
||||
"type": "n8n-nodes-base.html",
|
||||
"position": [
|
||||
2360,
|
||||
1280
|
||||
],
|
||||
"parameters": {
|
||||
"html": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\" />\n <title>{{ $json.output['Headline'] }}</title>\n</head>\n<body>\n <div class=\"container\">\n <img class=\"logo\" src=\"https://img.logoipsum.com/264.svg\"/>\n <h1>Hey {{ $json['Custome Name'] ? $json['Custome Name']+', ' : '!' }}</h1>\n <p>{{ $json.output['Body'] }}</p>\n \n <div class=\"coupon\">\n <h3>Here's a Coupon for you!<br>\n {{ $json['Coupon Value'] }}</h3>\n <h4 class=\"code\">{{ $json['Coupon'] }}</h4>\n <p>{{ $json['Coupon Terms'] }}</p>\n </div>\n <div class=\"footer\">\n <p>\n Definitely not a real company Lmt.<br>\n Also not a real street 123<br>\n Unreal Town\n </p> \n</div> \n </div>\n \n \n</body>\n</html>\n\n<style>\n.logo {\n margin-top: 20px;\n }\n.container {\n background-color: #ffffff;\n font-family: sans-serif;\n padding: 16px;\n border-radius: 8px;\n}\n\nh1 {\n color: #ff6d5a;\n font-size: 24px;\n font-weight: bold;\n margin-top: 30px;\n}\n\np {\n color: #606060;\n line-height: 1.6;\n}\n\nh2 {\n color: #909399;\n font-size: 20px;\n font-weight: bold;\n padding: 8px;\n}\n\n.coupon {\n background: #ff6d5a;\n color: #fff;\n padding: 20px;\n}\n.coupon p {\n color: #fff;\n}\n \n.coupon .code {\n font-weight: bold;\n font-size: 24px;\n font-family: monospace;\n }\n\n.footer {\n margin-top: 30px;\n}\n\n.footer > p {\n font-size: 14px;\n color: #ccc;\n }\n\n</style>"
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "2d5dd858-cf61-4136-b405-e6ad4a372725",
|
||||
"name": "The composed E-Mail with Coupon + Prev Data",
|
||||
"type": "n8n-nodes-base.merge",
|
||||
"position": [
|
||||
2740,
|
||||
1040
|
||||
],
|
||||
"parameters": {
|
||||
"mode": "combine",
|
||||
"options": {},
|
||||
"combineBy": "combineByPosition"
|
||||
},
|
||||
"typeVersion": 3
|
||||
},
|
||||
{
|
||||
"id": "5b1606b4-903a-4e90-8cf6-01fd92006195",
|
||||
"name": "Send Email",
|
||||
"type": "n8n-nodes-base.emailSend",
|
||||
"position": [
|
||||
3140,
|
||||
960
|
||||
],
|
||||
"webhookId": "a155d7b3-39b1-4a96-adc5-4f8e984506ec",
|
||||
"parameters": {
|
||||
"html": "={{ $json.html }}",
|
||||
"options": {},
|
||||
"subject": "={{ $json.output.Headline }}",
|
||||
"toEmail": "={{ $json.Email }}",
|
||||
"fromEmail": "n8n@myemail.com"
|
||||
},
|
||||
"credentials": {
|
||||
"smtp": {
|
||||
"id": "EagS3depRLAKo3Sw",
|
||||
"name": "Greenmail SMTP account (bob@example.com)"
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.1
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Fake coupon": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Html Template for our Email with a Coupon",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Extract from File": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Some Options for the Campaign",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"OpenAI Chat Model1": {
|
||||
"ai_languageModel": [
|
||||
[
|
||||
{
|
||||
"node": "Information Extractor",
|
||||
"type": "ai_languageModel",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Download dummy data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Extract from File",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Is the result valid?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Coupon them or not to Coupon them",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "AI did fail us1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"AI Output + Prev Data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Is the result valid?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Information Extractor": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "AI Output + Prev Data",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Html Template for our Email": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "The composed E-Mail + Prev Data",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Some Options for the Campaign": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Information Extractor",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "AI Output + Prev Data",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"The composed E-Mail + Prev Data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send Email",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Download dummy data",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Coupon them or not to Coupon them": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Html Template for our Email",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "The composed E-Mail + Prev Data",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Fake coupon",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "The composed E-Mail with Coupon + Prev Data",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Html Template for our Email with a Coupon": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "The composed E-Mail with Coupon + Prev Data",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"The composed E-Mail with Coupon + Prev Data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send Email",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,814 @@
|
||||
{
|
||||
"meta": {
|
||||
"instanceId": "9ca813d4011eeb6a3cfcfbfac1efbb98641b1341a64a5cad70c430777ffd407e"
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"id": "38cd304e-e260-4bbd-ace1-57b5fd0e6344",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"position": [
|
||||
-1300,
|
||||
360
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "087994ba-3b40-4337-b17a-e2ab4aa39963",
|
||||
"name": "Whether type is file",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
940,
|
||||
780
|
||||
],
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"string": [
|
||||
{
|
||||
"value1": "={{ $json.type }}",
|
||||
"value2": "file"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "ab2ec609-2c7a-4976-9ce0-57f6961578e1",
|
||||
"name": "Set new path for subfolder",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
1240,
|
||||
900
|
||||
],
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "from",
|
||||
"stringValue": "={{ decodeURIComponent($json.path) }}"
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"stringValue": "={{ decodeURIComponent($('Set folder-paths for from and to').item.json.to + '/' + $json.path.split('/').filter(Boolean).pop() + '/') }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": "none",
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 3.2
|
||||
},
|
||||
{
|
||||
"id": "98099141-0e7f-49f0-bfc9-67eef67b13aa",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
540,
|
||||
474.3406813627256
|
||||
],
|
||||
"parameters": {
|
||||
"width": 1861.9238476953906,
|
||||
"height": 665.3466933867735,
|
||||
"content": "## Get all files of subfolders\nIn this segment of the workflow, all files located within subfolders are collected. This includes the exploration of subfolders within subfolders, ensuring the identification of every file throughout the entire folder structure. Additionally, a corresponding folder is created in the destination structure for each identified subfolder."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "8284d632-f0a0-437e-9f75-6995c72400c2",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
2440,
|
||||
478.85370741482984
|
||||
],
|
||||
"parameters": {
|
||||
"width": 695.2464929859717,
|
||||
"height": 660.1721006751914,
|
||||
"content": "## Enrich the files\nIn this phase of the workflow, all identified files are processed and enriched with the correct path within the destination structure."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "f8b151e4-f9c9-474c-94f3-1c0d340d8e36",
|
||||
"name": "Set new path for file",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
2900,
|
||||
860
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "for (const item of $input.all()) {\n const toPath = $('Set folder-paths for from and to').item.json.to;\n const fromPath = $('Set folder-paths for from and to').item.json.from;\n\n // Remove leading and trailing slashes\n path = fromPath.replace(/^\\/|\\/$/g, '');\n // Split the path into an array of folders\n const folders = path.split('/');\n // Remove empty strings (resulting from leading, trailing, or consecutive slashes)\n const nonEmptyFoldersCount = folders.filter(folder => folder !== '').length;\n\n newFilePathArray = item.json.path.replace(/^\\/|\\/$/g, '').split('/');\n \n item.json.newPath = toPath.replace(/^\\/|\\/$/g, '') + '/' + newFilePathArray.slice(nonEmptyFoldersCount).join(\"/\")\n}\n\nreturn $input.all();"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "638426c9-c736-4ba9-91a2-383049f15ee5",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
3180,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"width": 695.2464929859717,
|
||||
"height": 658.7966837968969,
|
||||
"content": "## Move files \nIn this stage of the workflow, the files are moved into the destination structure.\n\nIf the batch size remains at 1 in the Loop Over node, each file will be moved sequentially. If the batch size is increased, multiple files will be moved simultaneously."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "96d83360-21ed-49f1-b273-47ee609f52fa",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
3920,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"width": 695.2464929859717,
|
||||
"height": 658.7966837968969,
|
||||
"content": "## (Optional) Delete *from*-folder\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "cd5dbcf2-378e-4102-9db2-0627c829e2f2",
|
||||
"name": "Sticky Note4",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-380,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"width": 871.7450543093198,
|
||||
"height": 665.3466933867735,
|
||||
"content": "## Get the files and subfolders to move\nIn this segment of the workflow, all files and subfolders to be relocated are gathered. Additionally, the destination folder is created if it does not already exist."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "91894912-7f54-447b-947b-4040fc92f094",
|
||||
"name": "Sticky Note5",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-1340,
|
||||
60
|
||||
],
|
||||
"parameters": {
|
||||
"width": 723.2756594453772,
|
||||
"height": 463.596247600301,
|
||||
"content": "## Manual Start\nTo manually initiate the workflow, the Set Paths node requires the specification of the folder path to be moved and the destination folder path. Subfolders can be indicated using '/'.\n\nEnsure that the other workflow triggers are deactivated before initiating the workflow."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c1e7754f-6efa-4967-9b8d-6c1bcdb55355",
|
||||
"name": "Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"disabled": true,
|
||||
"position": [
|
||||
-1320,
|
||||
880
|
||||
],
|
||||
"webhookId": "285b2cba-587b-4131-82a8-cdd35a8d49e1",
|
||||
"parameters": {
|
||||
"path": "285b2cba-587b-4131-82a8-cdd35a8d49e1",
|
||||
"options": {},
|
||||
"httpMethod": "POST",
|
||||
"responseData": "noData",
|
||||
"responseMode": "lastNode"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "cb3e0c28-afa4-4847-b95e-5c7523f18df6",
|
||||
"name": "Sticky Note6",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-1340,
|
||||
580
|
||||
],
|
||||
"parameters": {
|
||||
"width": 723.2756594453772,
|
||||
"height": 500.9028666051119,
|
||||
"content": "## Webhook trigger\nYou can also automate the workflow by configuring a webhook to trigger it. It is crucial that each request contains a JSON body with at least the two attributes 'from-path' and 'to-path' set. Here is an example:\n\n```\n{\n \"from\": \"Folder/to/move\",\n \"to\": \"New-Folder\"\n}\n```\n\nThe workflow will respond with an error, if the request is not valid.\n\nEnsure that the other workflow triggers are deactivated before initiating the workflow."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "3c85f4a4-28b3-4315-b689-033e4af3f888",
|
||||
"name": "Sticky Note7",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-1340,
|
||||
1140
|
||||
],
|
||||
"parameters": {
|
||||
"width": 723.2756594453772,
|
||||
"height": 498.6039613328509,
|
||||
"content": "## Trigger by other workflow\nIt is also possible to initiate this workflow from within another workflow. It is important to ensure that at least the 'from-path' and 'to-path' are passed as parameters when starting this workflow.\n\nThe workflow will respond with an error, if the request is not valid.\n\nEnsure that the other workflow triggers are deactivated before initiating the workflow."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "88e63d18-7c68-4d4f-bfe6-5780115d3ed0",
|
||||
"name": "Execute Workflow Trigger",
|
||||
"type": "n8n-nodes-base.executeWorkflowTrigger",
|
||||
"disabled": true,
|
||||
"position": [
|
||||
-1320,
|
||||
1440
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "82d7182e-3aca-4407-8faa-3704429974dc",
|
||||
"name": "Set folder-paths for from and to",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
-280,
|
||||
880
|
||||
],
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "from",
|
||||
"stringValue": "={{ $json.from }}"
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"stringValue": "={{ $json.to }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 3.2
|
||||
},
|
||||
{
|
||||
"id": "e9edad54-d5f2-481e-b5be-b43a15b74233",
|
||||
"name": "Create to folder if necessary",
|
||||
"type": "n8n-nodes-base.nextCloud",
|
||||
"onError": "continueRegularOutput",
|
||||
"position": [
|
||||
-40,
|
||||
880
|
||||
],
|
||||
"parameters": {
|
||||
"path": "={{ $json.to }}",
|
||||
"resource": "folder"
|
||||
},
|
||||
"credentials": {
|
||||
"nextCloudApi": {
|
||||
"id": "kd8dB6PqsIKQhB6O",
|
||||
"name": "NextCloud account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "4283f069-ea26-499d-928c-5f0f3898cdc4",
|
||||
"name": "Get all folders/files in from-folder",
|
||||
"type": "n8n-nodes-base.nextCloud",
|
||||
"position": [
|
||||
240,
|
||||
880
|
||||
],
|
||||
"parameters": {
|
||||
"path": "={{ $('Set folder-paths for from and to').item.json.from }}",
|
||||
"resource": "folder",
|
||||
"operation": "list"
|
||||
},
|
||||
"credentials": {
|
||||
"nextCloudApi": {
|
||||
"id": "kd8dB6PqsIKQhB6O",
|
||||
"name": "NextCloud account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "06c77d03-d79b-4435-9f7f-eef919b7b6af",
|
||||
"name": "Loop over files and folders",
|
||||
"type": "n8n-nodes-base.splitInBatches",
|
||||
"position": [
|
||||
660,
|
||||
880
|
||||
],
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 3
|
||||
},
|
||||
{
|
||||
"id": "56cc28ea-d934-4d9c-9e28-968c2e1fa4da",
|
||||
"name": "Consolidate all files and folders found",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"position": [
|
||||
2000,
|
||||
760
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "57883a8f-7989-4706-808a-595376ebaf47",
|
||||
"name": "Create subfolder in to-folder",
|
||||
"type": "n8n-nodes-base.nextCloud",
|
||||
"onError": "continueRegularOutput",
|
||||
"position": [
|
||||
1440,
|
||||
900
|
||||
],
|
||||
"parameters": {
|
||||
"path": "={{$('Set new path for subfolder').item.json.to }}",
|
||||
"resource": "folder"
|
||||
},
|
||||
"credentials": {
|
||||
"nextCloudApi": {
|
||||
"id": "kd8dB6PqsIKQhB6O",
|
||||
"name": "NextCloud account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "0a173b88-53c5-44b1-ae04-f68b343025ce",
|
||||
"name": "Get all folders/files in found subfolder",
|
||||
"type": "n8n-nodes-base.nextCloud",
|
||||
"position": [
|
||||
1680,
|
||||
900
|
||||
],
|
||||
"parameters": {
|
||||
"path": "={{$('Set new path for subfolder').item.json.from }}",
|
||||
"resource": "folder",
|
||||
"operation": "list"
|
||||
},
|
||||
"credentials": {
|
||||
"nextCloudApi": {
|
||||
"id": "kd8dB6PqsIKQhB6O",
|
||||
"name": "NextCloud account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "3c17b67c-e815-4e27-9b63-19346cb8b966",
|
||||
"name": "Whether there is are more files or subfolders found",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
2200,
|
||||
880
|
||||
],
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{$node[\"Loop over files and folders\"].context[\"noItemsLeft\"]}}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "94c4e926-eb92-4b10-8d35-2b3483cc4819",
|
||||
"name": "Consolidate all found files",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
2580,
|
||||
860
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "let results = [],\n i = 0;\n\ndo {\n try {\n results = results.concat($(\"Consolidate all files and folders found\").all(0, i));\n } catch (error) {\n return results;\n }\n i++;\n} while (true);"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "b40e30ff-793c-46e6-b5a0-5498ee27a3c9",
|
||||
"name": "Loop Over all files",
|
||||
"type": "n8n-nodes-base.splitInBatches",
|
||||
"position": [
|
||||
3300,
|
||||
860
|
||||
],
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 3
|
||||
},
|
||||
{
|
||||
"id": "034c66f7-c184-438d-96de-1d20f8f7adc5",
|
||||
"name": "Move file to destination",
|
||||
"type": "n8n-nodes-base.nextCloud",
|
||||
"position": [
|
||||
3660,
|
||||
940
|
||||
],
|
||||
"parameters": {
|
||||
"path": "={{ decodeURIComponent($json.path) }}",
|
||||
"toPath": "={{ decodeURIComponent($json.newPath) }}",
|
||||
"operation": "move"
|
||||
},
|
||||
"credentials": {
|
||||
"nextCloudApi": {
|
||||
"id": "kd8dB6PqsIKQhB6O",
|
||||
"name": "NextCloud account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "34c8521f-cb17-479f-842b-38cbb5970403",
|
||||
"name": "Delete from-folder",
|
||||
"type": "n8n-nodes-base.nextCloud",
|
||||
"onError": "continueRegularOutput",
|
||||
"position": [
|
||||
4200,
|
||||
840
|
||||
],
|
||||
"parameters": {
|
||||
"path": "={{ $('Set folder-paths for from and to').item.json.from }}",
|
||||
"resource": "folder",
|
||||
"operation": "delete"
|
||||
},
|
||||
"credentials": {
|
||||
"nextCloudApi": {
|
||||
"id": "kd8dB6PqsIKQhB6O",
|
||||
"name": "NextCloud account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "eeda26a3-f5e6-4e6d-aeca-ebe2dbc2cb9e",
|
||||
"name": "Set paths",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
-780,
|
||||
360
|
||||
],
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "from",
|
||||
"stringValue": "Old-Folder"
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"stringValue": "Destination"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 3.2
|
||||
},
|
||||
{
|
||||
"id": "ba2e352a-4911-470b-a3bb-f63e3470e228",
|
||||
"name": "Whether the request is valid",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
-1100,
|
||||
880
|
||||
],
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.hasOwnProperty('body') && $json.body.hasOwnProperty('to') && $json.body.hasOwnProperty('from')}}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "ed4ddbf1-becf-4944-abd4-0b4cdf6d3b85",
|
||||
"name": "Stop and Error: request not valid",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
-760,
|
||||
920
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "The Request is not valid!"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "2b5d67ac-983b-486d-99f1-e05995383878",
|
||||
"name": "Whether the request is valid1",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
-1120,
|
||||
1440
|
||||
],
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.hasOwnProperty('to') && $json.hasOwnProperty('from')}}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "b57309cf-2a69-4879-a7d4-5499f8278e3b",
|
||||
"name": "Stop and Error: request not valid1",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
-760,
|
||||
1480
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "The Request is not valid!"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "f109308f-0b48-4395-9f2d-c8b4e8d936d2",
|
||||
"name": "Sticky Note8",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-2440,
|
||||
60
|
||||
],
|
||||
"parameters": {
|
||||
"width": 770.5015081009478,
|
||||
"height": 1247.9320267653952,
|
||||
"content": "# Template Description\n\n\n## Description:\nThis template facilitates the transfer of a folder, along with all its files and subfolders, within a Nextcloud instance. The Nextcloud user must have access to both the source and destination folders. While Nextcloud allows folder movement, complications may arise when dealing with external storage that has rate limits. This workflow ensures the individual transfer of each file to avoid exceeding rate limits, particularly useful for setups involving external storage with rate limitations.\n\n## How it works:\n\n- Identify all files and subfolders within the specified source folder.\n- Recursive search within subfolders for additional files.\n- Replicate the folder structure in the target folder.\n- Individually move each identified file to the corresponding location in the target folder.\n\n## Set up steps:\n\n- Set Nextcloud credentials for all Nextcloud nodes involved in the process.\n-Edit the trigger settings. Detailed instructions can be found within the respective trigger configuration.\n- Initiate the workflow to commence the folder transfer process.\n\n\n## Help\nIf you need assistance with applying this template, feel free to reach out to me. You can find additional information about me and my services here. => https://nicokowalczyk.de/links\n\nI have also produced a video where I explain the workflow and provide an example. You can find this video over here. https://youtu.be/K1kmG_Q_jRk\n\nCheers.\nNico Kowalczyk"
|
||||
},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Whether the request is valid",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set paths": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set folder-paths for from and to",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Loop Over all files": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Delete from-folder",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Move file to destination",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Whether type is file": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Consolidate all files and folders found",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Set new path for subfolder",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set new path for file": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Loop Over all files",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Workflow Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Whether the request is valid1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Move file to destination": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Loop Over all files",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set new path for subfolder": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Create subfolder in to-folder",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Consolidate all found files": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set new path for file",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Loop over files and folders": {
|
||||
"main": [
|
||||
null,
|
||||
[
|
||||
{
|
||||
"node": "Whether type is file",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Whether the request is valid": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set folder-paths for from and to",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error: request not valid",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Create subfolder in to-folder": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get all folders/files in found subfolder",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Create to folder if necessary": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get all folders/files in from-folder",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Whether the request is valid1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set folder-paths for from and to",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error: request not valid1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set folder-paths for from and to": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Create to folder if necessary",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set paths",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get all folders/files in from-folder": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Loop over files and folders",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Consolidate all files and folders found": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Whether there is are more files or subfolders found",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get all folders/files in found subfolder": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Consolidate all files and folders found",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Whether there is are more files or subfolders found": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Consolidate all found files",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Loop over files and folders",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,343 @@
|
||||
{
|
||||
"meta": {
|
||||
"instanceId": "2edac0e72822bb0462c05ce3b5a939f685ded652d02e9a767d1afa775988460e"
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"id": "0788a3db-20c3-43b6-956a-394f688f7763",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"position": [
|
||||
360,
|
||||
440
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "51460fab-a53c-46cd-a484-d2c038cd102d",
|
||||
"name": "Schedule Trigger",
|
||||
"type": "n8n-nodes-base.scheduleTrigger",
|
||||
"position": [
|
||||
360,
|
||||
600
|
||||
],
|
||||
"parameters": {
|
||||
"rule": {
|
||||
"interval": [
|
||||
{
|
||||
"triggerAtHour": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "5326416c-5715-4cc7-acfd-38a32f864bfb",
|
||||
"name": "loop",
|
||||
"type": "n8n-nodes-base.splitInBatches",
|
||||
"position": [
|
||||
1360,
|
||||
600
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"batchSize": 1
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "fb0ca9f7-ff49-4a4b-9575-42b80594737e",
|
||||
"name": "sitemap_set",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
540,
|
||||
600
|
||||
],
|
||||
"parameters": {
|
||||
"url": "https://bushidogym.fr/sitemap.xml",
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 4.1
|
||||
},
|
||||
{
|
||||
"id": "150b47fe-f1c8-4dcb-b187-b459ee50c316",
|
||||
"name": "sitemap_convert",
|
||||
"type": "n8n-nodes-base.xml",
|
||||
"position": [
|
||||
700,
|
||||
600
|
||||
],
|
||||
"parameters": {
|
||||
"options": {
|
||||
"trim": true,
|
||||
"normalize": true,
|
||||
"mergeAttrs": true,
|
||||
"ignoreAttrs": true,
|
||||
"normalizeTags": true
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "83cd19d6-81e7-46af-83a3-090cdd66b420",
|
||||
"name": "sitemap_parse",
|
||||
"type": "n8n-nodes-base.splitOut",
|
||||
"position": [
|
||||
920,
|
||||
600
|
||||
],
|
||||
"parameters": {
|
||||
"options": {
|
||||
"destinationFieldName": "url"
|
||||
},
|
||||
"fieldToSplitOut": "urlset.url"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "95c784d1-5756-4bf0-b2e5-e25a84c01b72",
|
||||
"name": "url_set",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
1140,
|
||||
600
|
||||
],
|
||||
"parameters": {
|
||||
"values": {
|
||||
"string": [
|
||||
{
|
||||
"name": "url",
|
||||
"value": "={{ $json.url.loc }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {},
|
||||
"keepOnlySet": true
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "43b62667-a37e-4bd1-bbb9-7a20a0914c97",
|
||||
"name": "url_index",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
1560,
|
||||
580
|
||||
],
|
||||
"parameters": {
|
||||
"url": "https://indexing.googleapis.com/v3/urlNotifications:publish",
|
||||
"method": "POST",
|
||||
"options": {},
|
||||
"sendBody": true,
|
||||
"authentication": "predefinedCredentialType",
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "url",
|
||||
"value": "={{ $json.url }}"
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"value": "URL_UPDATED"
|
||||
}
|
||||
]
|
||||
},
|
||||
"nodeCredentialType": "googleApi"
|
||||
},
|
||||
"credentials": {
|
||||
"googleApi": {
|
||||
"id": "RywvL8c7V2ZtBvdK",
|
||||
"name": "850737154850-compute@developer.gserviceaccount.com"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4,
|
||||
"continueOnFail": true,
|
||||
"alwaysOutputData": true
|
||||
},
|
||||
{
|
||||
"id": "39ae8c01-64e4-44f5-be43-d5c402b00739",
|
||||
"name": "index_check",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
1780,
|
||||
580
|
||||
],
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"string": [
|
||||
{
|
||||
"value1": "={{ $json.urlNotificationMetadata.latestUpdate.type }}",
|
||||
"value2": "URL_UPDATED"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c4bf483b-af4b-451e-974b-d4abeb2c70f6",
|
||||
"name": "wait",
|
||||
"type": "n8n-nodes-base.wait",
|
||||
"position": [
|
||||
2040,
|
||||
560
|
||||
],
|
||||
"webhookId": "b0df1fe8-e509-4d0c-a486-f523226621e2",
|
||||
"parameters": {
|
||||
"unit": "seconds",
|
||||
"amount": 2
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "455955a8-c767-453b-805c-77c5b7d2e9bc",
|
||||
"name": "Stop and Error",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
2040,
|
||||
840
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "You have reached the Google Indexing API limit (200/day by default)"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "275abdd5-be5d-458f-bc75-d9f72824c49f",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
340,
|
||||
180
|
||||
],
|
||||
"parameters": {
|
||||
"width": 482.7089688834655,
|
||||
"height": 221.39109212934721,
|
||||
"content": "## Simple indexing workflow using the Google Indexing API\n\nThis workflow is the simplest indexing workflow. It simply extracts a sitemap, converts it to a JSON, and loops through each URL. It will output an error if your quota is reached.\n\n*Joachim*"
|
||||
},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"loop": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "url_index",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"wait": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "loop",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"url_set": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "loop",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"url_index": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "index_check",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"index_check": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "wait",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"sitemap_set": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "sitemap_convert",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"sitemap_parse": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "url_set",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"sitemap_convert": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "sitemap_parse",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Schedule Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "sitemap_set",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "sitemap_set",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,498 @@
|
||||
{
|
||||
"meta": {
|
||||
"instanceId": "9e331a89ae45a204c6dee51c77131d32a8c962ec20ccf002135ea60bd285dba9"
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"id": "d72750fc-6415-4da6-977a-46d025a91ef9",
|
||||
"name": "When clicking ‘Test workflow’",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"position": [
|
||||
-900,
|
||||
900
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "b00e7434-f83e-438e-a47b-12d4a2c4fe5b",
|
||||
"name": "List Invoices",
|
||||
"type": "n8n-nodes-base.splitOut",
|
||||
"position": [
|
||||
180,
|
||||
900
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"fieldToSplitOut": "data"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c142f60b-dbbd-444a-b39b-365e9eb1ff58",
|
||||
"name": "Inject s3 Subpath",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
820,
|
||||
640
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "dca623a6-834c-440f-990a-25bfd9afa2b3",
|
||||
"name": "_s3_year",
|
||||
"type": "string",
|
||||
"value": "={{ DateTime.fromSeconds($json.created).format(\"yyyy\") }}"
|
||||
},
|
||||
{
|
||||
"id": "55ab18e0-b2ef-486d-898d-97f671d5049b",
|
||||
"name": "_s3_folder",
|
||||
"type": "string",
|
||||
"value": "={{ $(\"Clean and Escape ENV\").first().json.subFolder }}"
|
||||
},
|
||||
{
|
||||
"id": "7f998728-a70e-4495-8d34-3ba72a71986b",
|
||||
"name": "_s3_month",
|
||||
"type": "string",
|
||||
"value": "={{ DateTime.fromSeconds($json.created).format(\"MM\") }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"includeOtherFields": true
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "4cdd4338-7225-442b-8df6-44bebfe6d5e9",
|
||||
"name": "Set-Subpath",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
1000,
|
||||
640
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "f2969361-8ed9-453b-8c71-e5b3c962af20",
|
||||
"name": "_s3_path",
|
||||
"type": "string",
|
||||
"value": "={{ ($json._s3_folder ? $json._s3_folder+\"/\" : \"\")+$json._s3_year+\"/\"+$json._s3_month+\"/\"+$binary.data.fileName }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"includeOtherFields": true
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "4965110b-0516-4a5d-9b04-8ccbb337f9d5",
|
||||
"name": "We do only Invoice Objects",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
360,
|
||||
900
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "2bdd8550-526c-4833-872e-b1028019a88a",
|
||||
"operator": {
|
||||
"name": "filter.operator.equals",
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
},
|
||||
"leftValue": "={{ $json.object }}",
|
||||
"rightValue": "invoice"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "def30f79-593f-48b3-b46f-29c5329a59ae",
|
||||
"name": "It shouldn't be something else",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
580,
|
||||
1042.3086136912689
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "Unexpected or missing Invoice Obj"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "927c4bbd-5a57-4929-aebb-b187690108ac",
|
||||
"name": "ENV*",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
-500,
|
||||
900
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "b2927be9-2b00-4ab8-8938-56b1a0c2e134",
|
||||
"name": "year",
|
||||
"type": "number",
|
||||
"value": "={{ $now.minus(1,\"month\").format(\"yyyy\") }}"
|
||||
},
|
||||
{
|
||||
"id": "89e0c6ee-7b67-405a-b933-5a511cdea94b",
|
||||
"name": "month",
|
||||
"type": "number",
|
||||
"value": "={{ $now.minus(1,\"month\").format(\"MM\") }}"
|
||||
},
|
||||
{
|
||||
"id": "35a218d2-cd20-4388-8bc6-926752289df5",
|
||||
"name": "subFolder",
|
||||
"type": "string",
|
||||
"value": "invoices"
|
||||
},
|
||||
{
|
||||
"id": "7d18829a-018d-4814-987e-cdbee04896b3",
|
||||
"name": "bucketName",
|
||||
"type": "string",
|
||||
"value": "myBucket"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "dd75af83-6e0a-4685-a3bd-1622e2c800de",
|
||||
"name": "Download Invoice PDF from Stripe",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
580,
|
||||
640
|
||||
],
|
||||
"parameters": {
|
||||
"url": "={{ $json.invoice_pdf }}",
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "30c4090d-043c-4b3b-b86c-df1e10544b2e",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-600,
|
||||
802.3086136912689
|
||||
],
|
||||
"parameters": {
|
||||
"color": 4,
|
||||
"width": 305.7072653471566,
|
||||
"height": 670.9306322684054,
|
||||
"content": "## 👇 Configure here\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n`folderName` *(optional)* = Subfolder for your Invoices, otherwise it will create in root. e.g: \"invoices\"\n\n`bucketName` *(required)* = the S3 Bucket Name, where invoices will be synced in\n\n`year` (automatic or hardcore) = \nthe expression makes sure it will be exporting \"last month\". Or define a custom year for manual export.\n\n`month` (automatic or hardcore) = \nthe expression makes sure it will be exporting \"last month\". Or define a custom month for manual export.\n\n\n**EVERYTHING** greater then the **provided date** will be exported. The Day will be always the first of month."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "4134f369-84de-4019-a014-1d823ec77668",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
780,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"color": 5,
|
||||
"width": 362.3514596119466,
|
||||
"height": 336.03175807685056,
|
||||
"content": "## Build Pathes\n\n*yourFolder/invoiceYear/invoiceMonth/fileName*\n\ne.g.: invoices/2024/12/invoice-number-123.pdf"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c8ecef82-ef73-4920-b9fa-16220009f7d9",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1203.398651655887,
|
||||
482.2657677705912
|
||||
],
|
||||
"parameters": {
|
||||
"width": 283.04958764124035,
|
||||
"height": 329.9325827943702,
|
||||
"content": "## Upload to Bucket\n\n**⚠️ You might want to check Storage Class, ACL, etc.**"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "a0505cc0-8312-46f2-970d-bfabff881ced",
|
||||
"name": "Every Month the First Day of the Month",
|
||||
"type": "n8n-nodes-base.scheduleTrigger",
|
||||
"position": [
|
||||
-900,
|
||||
1102.3086136912689
|
||||
],
|
||||
"parameters": {
|
||||
"rule": {
|
||||
"interval": [
|
||||
{
|
||||
"field": "months"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "53ee7468-f478-4c10-8767-1aa7967b3225",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-100,
|
||||
820
|
||||
],
|
||||
"parameters": {
|
||||
"width": 232,
|
||||
"height": 256,
|
||||
"content": "### Use Stripe Predefined Credential"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "6055b93d-0462-4d1a-974a-7d31143e6b79",
|
||||
"name": "Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-1360,
|
||||
780
|
||||
],
|
||||
"parameters": {
|
||||
"width": 367.15098241985504,
|
||||
"height": 485.66522445338995,
|
||||
"content": "## Instructions\n\nThis automation syncs monthly your Invoice PDF from Stripe to a (AWS) S3 Bucket of your choice with the following subPaths (Key):\n\n*yourFolder/invoiceYear/invoiceMonth/fileName*\n\n\nFill in your **Credentials and Settings** in the Nodes marked with _\"*\"_.\n\nYou can adjust this Workflow to your needs. You can also override the `year`and `month` in the ENV* Node for manual syncs.\n\n\nEnjoy the Workflow! ❤️ \nhttps://let-the-work-flow.com\nWorkflow Automation & Development"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c5e5946c-c74f-435f-9664-491bbbca00f2",
|
||||
"name": "Get all Invoices*",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
-40,
|
||||
900
|
||||
],
|
||||
"parameters": {
|
||||
"url": "https://api.stripe.com/v1/invoices",
|
||||
"options": {},
|
||||
"sendQuery": true,
|
||||
"authentication": "predefinedCredentialType",
|
||||
"queryParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "limit",
|
||||
"value": "100"
|
||||
},
|
||||
{
|
||||
"name": "created[gte]",
|
||||
"value": "={{ DateTime.fromISO($json.year+\"-\"+$json.month+\"-01T00:00:00\").toSeconds() }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"nodeCredentialType": "stripeApi"
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "5ed183d2-3001-40ef-9dc6-897c6789209a",
|
||||
"name": "Upload to S3 Bucket*",
|
||||
"type": "n8n-nodes-base.awsS3",
|
||||
"position": [
|
||||
1280,
|
||||
640
|
||||
],
|
||||
"parameters": {
|
||||
"fileName": "={{ $json._s3_path }}",
|
||||
"operation": "upload",
|
||||
"bucketName": "={{ $(\"Clean and Escape ENV\").first().json.bucketName }}",
|
||||
"additionalFields": {
|
||||
"storageClass": "intelligentTiering"
|
||||
}
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "04b57622-64b2-4c62-b84b-61d49c3171fb",
|
||||
"name": "Clean and Escape ENV",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
-240,
|
||||
900
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "2d053eee-92a2-44ee-ad34-b1ad87728285",
|
||||
"name": "bucketName",
|
||||
"type": "string",
|
||||
"value": "={{ $json.bucketName.trim().replace(/\\\\/g, '') }}"
|
||||
},
|
||||
{
|
||||
"id": "ccd36bf6-91f3-44af-8b57-3002041c9829",
|
||||
"name": "subFolder",
|
||||
"type": "string",
|
||||
"value": "={{ $json.subFolder.trim().replace(/\\\\/g, '') }}"
|
||||
},
|
||||
{
|
||||
"id": "0fb9451f-afc1-4b70-9ec3-f3ac7187c2db",
|
||||
"name": "month",
|
||||
"type": "string",
|
||||
"value": "={{ $json.month.toString().padStart(2,\"0\") }}"
|
||||
},
|
||||
{
|
||||
"id": "eda1110d-329b-4d12-a089-253ac189aea4",
|
||||
"name": "year",
|
||||
"type": "number",
|
||||
"value": "={{ parseInt($json.year) }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"includeOtherFields": true
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"ENV*": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Clean and Escape ENV",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set-Subpath": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Upload to S3 Bucket*",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"List Invoices": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "We do only Invoice Objects",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get all Invoices*": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "List Invoices",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Inject s3 Subpath": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set-Subpath",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Clean and Escape ENV": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get all Invoices*",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"We do only Invoice Objects": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Download Invoice PDF from Stripe",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "It shouldn't be something else",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Download Invoice PDF from Stripe": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Inject s3 Subpath",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"When clicking ‘Test workflow’": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "ENV*",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Every Month the First Day of the Month": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "ENV*",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,256 @@
|
||||
{
|
||||
"id": "2NhqmUqW3KruEkaE",
|
||||
"meta": {
|
||||
"instanceId": "d868e3d040e7bda892c81b17cf446053ea25d2556fcef89cbe19dd61a3e876e9"
|
||||
},
|
||||
"name": "Exponential Backoff for Google APIs",
|
||||
"tags": [
|
||||
{
|
||||
"id": "nezaWFCGa7eZsVKu",
|
||||
"name": "Utility",
|
||||
"createdAt": "2024-11-13T18:08:08.207Z",
|
||||
"updatedAt": "2024-11-13T18:08:08.207Z"
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "5d6b1730-33c5-401c-b73f-2b7ea8eedfe3",
|
||||
"name": "When clicking ‘Test workflow’",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"position": [
|
||||
-580,
|
||||
-80
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "6726b630-597c-46cf-8839-75cd80108f2f",
|
||||
"name": "Exponential Backoff",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
160,
|
||||
120
|
||||
],
|
||||
"parameters": {
|
||||
"mode": "runOnceForEachItem",
|
||||
"jsCode": "// Define the retry count (coming from a previous node or set manually)\nconst retryCount = $json[\"retryCount\"] || 0; // If not present, default to 0\nconst maxRetries = 5; // Define the maximum number of retries\nconst initialDelay = 1; // Initial delay in seconds (1 second)\n\n// If the retry count is less than the max retries, calculate the delay\nif (retryCount < maxRetries) {\n const currentDelayInSeconds = initialDelay * Math.pow(2, retryCount); // Exponential backoff delay in seconds\n \n // Log the delay time for debugging\n console.log(`Waiting for ${currentDelayInSeconds} seconds before retry...`);\n \n return {\n json: {\n retryCount: retryCount + 1, // Increment retry count\n waitTimeInSeconds: currentDelayInSeconds, // Pass the delay time in seconds\n status: 'retrying',\n }\n };\n} else {\n // If max retries are exceeded, return a failure response\n return {\n json: {\n error: 'Max retries exceeded',\n retryCount: retryCount,\n status: 'failed'\n }\n };\n}\n"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "605b8ff0-aa19-42dd-8dbb-aa12380ac4bc",
|
||||
"name": "Stop and Error",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
760,
|
||||
120
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "Google Sheets API Limit has been triggered and the workflow has stopped"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "97818e8b-e0cc-4a49-8797-43e02535740f",
|
||||
"name": "Loop Over Items",
|
||||
"type": "n8n-nodes-base.splitInBatches",
|
||||
"position": [
|
||||
-360,
|
||||
-80
|
||||
],
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 3
|
||||
},
|
||||
{
|
||||
"id": "0583eabd-bd97-4330-8a38-b2aed3a90c37",
|
||||
"name": "Google Sheets",
|
||||
"type": "n8n-nodes-base.googleSheets",
|
||||
"onError": "continueErrorOutput",
|
||||
"position": [
|
||||
-120,
|
||||
20
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"sheetName": {
|
||||
"__rl": true,
|
||||
"mode": "name",
|
||||
"value": "Sheet1"
|
||||
},
|
||||
"documentId": {
|
||||
"__rl": true,
|
||||
"mode": "url",
|
||||
"value": "https://docs.google.com/spreadsheets/d/1_gxZl6n_AYPHRFRTWfhy7TZnhEYuWzh8UvGdtWCD3sU/edit?gid=0#gid=0"
|
||||
},
|
||||
"authentication": "serviceAccount"
|
||||
},
|
||||
"credentials": {
|
||||
"googleApi": {
|
||||
"id": "lm7dPHYumCy6sP6k",
|
||||
"name": "AlexK1919 Google Service"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.5
|
||||
},
|
||||
{
|
||||
"id": "0d8023f8-f7ac-4303-b18e-821690cc9f94",
|
||||
"name": "Wait",
|
||||
"type": "n8n-nodes-base.wait",
|
||||
"position": [
|
||||
360,
|
||||
120
|
||||
],
|
||||
"webhookId": "f1651aa1-6497-4496-9e07-240dcf1852f3",
|
||||
"parameters": {
|
||||
"amount": "={{ $json[\"waitTime\"] }}"
|
||||
},
|
||||
"typeVersion": 1.1
|
||||
},
|
||||
{
|
||||
"id": "72e0001e-f99b-4d57-9006-4a4dd5d3d8d5",
|
||||
"name": "Check Max Retries",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
560,
|
||||
120
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "51e191cb-af20-423b-9303-8523caa4ae0d",
|
||||
"operator": {
|
||||
"type": "number",
|
||||
"operation": "gt"
|
||||
},
|
||||
"leftValue": "={{ $('Exponential Backoff').item.json[\"retryCount\"] }}",
|
||||
"rightValue": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "2ea14bb0-4313-4595-811d-729ca6d37420",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
100,
|
||||
-80
|
||||
],
|
||||
"parameters": {
|
||||
"color": 3,
|
||||
"width": 820,
|
||||
"height": 460,
|
||||
"content": "# Exponential Backoff for Google APIs \n## Connect these nodes to any Google API node such as the Google Sheets node example in this workflow"
|
||||
},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"active": false,
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "729e3a54-6238-4e4c-833e-8e37dba16dbb",
|
||||
"connections": {
|
||||
"Wait": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check Max Retries",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Google Sheets": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Loop Over Items",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Exponential Backoff",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Loop Over Items": {
|
||||
"main": [
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Google Sheets",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check Max Retries": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Google Sheets",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Exponential Backoff": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Wait",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Check Max Retries",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"When clicking ‘Test workflow’": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Loop Over Items",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,581 @@
|
||||
{
|
||||
"meta": {
|
||||
"instanceId": "568298fde06d3db80a2eea77fe5bf45f0c7bb898dea20b769944e9ac7c6c5a80"
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"id": "99bbf837-2834-4cae-af13-37b6cdf963bb",
|
||||
"name": "Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"position": [
|
||||
-480,
|
||||
-40
|
||||
],
|
||||
"webhookId": "83f4e1de-2011-487c-a9f7-be6ccbac0782",
|
||||
"parameters": {
|
||||
"path": "83f4e1de-2011-487c-a9f7-be6ccbac0782",
|
||||
"options": {},
|
||||
"httpMethod": "POST"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "0f7c13ea-196b-40a7-bf1e-4829caaaba4c",
|
||||
"name": "Stop and Error",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
180,
|
||||
60
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "Invalid verification token"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "7ddb4cfc-5917-4b19-acf8-c7db3eaab56a",
|
||||
"name": "Donation",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
400,
|
||||
-420
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "67607a8e-55e2-46ec-92f5-1c8ef3addf9c",
|
||||
"name": "from_name",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.from_name }}"
|
||||
},
|
||||
{
|
||||
"id": "3e6e86ac-b6c2-4b5f-9e33-22367b9fb9e5",
|
||||
"name": "message",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.message }}"
|
||||
},
|
||||
{
|
||||
"id": "4973525a-21b0-442c-8919-24c312f3ff0c",
|
||||
"name": "amount",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.amount }}"
|
||||
},
|
||||
{
|
||||
"id": "b7e2d9e1-61c2-4ad1-9cbd-d8a754993fbe",
|
||||
"name": "url",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.email }}"
|
||||
},
|
||||
{
|
||||
"id": "da26860f-c1c4-4918-9447-ed080e921fe7",
|
||||
"name": "currency",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.currency }}"
|
||||
},
|
||||
{
|
||||
"id": "380dbd53-eb04-4659-aa54-b6bde0ba7034",
|
||||
"name": "is_public",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.is_public }}"
|
||||
},
|
||||
{
|
||||
"id": "4fd65c21-3043-4513-96b3-d2e11656e94a",
|
||||
"name": "timestamp",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.timestamp }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "9c29ae0e-d80c-4613-ba11-535cc59d5603",
|
||||
"name": "Subscription",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
400,
|
||||
-140
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "886b9cca-15b1-49b4-a123-6f3ceb46279e",
|
||||
"name": "timestamp",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.timestamp }}"
|
||||
},
|
||||
{
|
||||
"id": "3c4d9c0e-3cd6-41d2-8223-c48f1dcccedc",
|
||||
"name": "from_name",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.from_name }}"
|
||||
},
|
||||
{
|
||||
"id": "7199ad4d-06ad-4bed-939b-e97d6d118d9b",
|
||||
"name": "message",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.message }}"
|
||||
},
|
||||
{
|
||||
"id": "270eeac1-b7f9-4cfb-9ac8-b0799b36482e",
|
||||
"name": "amount",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.amount }}"
|
||||
},
|
||||
{
|
||||
"id": "dbf3a671-715c-4e29-96d5-2767b6a620d8",
|
||||
"name": "url",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.url }}"
|
||||
},
|
||||
{
|
||||
"id": "79ae8427-e5fe-470f-bdc0-df0d8bcbad00",
|
||||
"name": "email",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.email }}"
|
||||
},
|
||||
{
|
||||
"id": "90c73e4d-197a-4ba3-b6fb-b7b79b62e69c",
|
||||
"name": "currency",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.currency }}"
|
||||
},
|
||||
{
|
||||
"id": "3e23aaad-70f4-429b-bee1-3ae0156aaa86",
|
||||
"name": "is_first_subscription_payment",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.is_first_subscription_payment }}"
|
||||
},
|
||||
{
|
||||
"id": "3ca5ca22-d8b7-4a90-a97e-aaed032ef705",
|
||||
"name": "tier_name",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.tier_name }}"
|
||||
},
|
||||
{
|
||||
"id": "1347258b-1f6d-4d44-bd64-95fb948cbff9",
|
||||
"name": "is_public",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.is_public }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "a050d88e-bbe8-4ee1-b1c6-31782b5b2f20",
|
||||
"name": "Shop Order",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
400,
|
||||
140
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "9f2d01f6-d172-4aea-b2ea-e64857592191",
|
||||
"name": "from_name",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.from_name }}"
|
||||
},
|
||||
{
|
||||
"id": "bbc1fcba-ec29-4599-9d78-4e1a37ecede3",
|
||||
"name": "amount",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.amount }}"
|
||||
},
|
||||
{
|
||||
"id": "2ea190ac-700b-4682-9baa-7d733f89b819",
|
||||
"name": "email",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.email }}"
|
||||
},
|
||||
{
|
||||
"id": "eb0af9d5-9650-4457-b0fd-44f679972a79",
|
||||
"name": "currency",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.currency }}"
|
||||
},
|
||||
{
|
||||
"id": "9acec88b-61d5-4520-bf51-f71b4e2e26f6",
|
||||
"name": "shop_items",
|
||||
"type": "array",
|
||||
"value": "={{ $json.body.shop_items }}"
|
||||
},
|
||||
{
|
||||
"id": "2e1fb035-b32c-492f-9705-7159ef0b2c5d",
|
||||
"name": "url",
|
||||
"type": "string",
|
||||
"value": "={{ $json.body.url }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "f9926fda-9a37-467e-b86b-ce9dbb051a88",
|
||||
"name": "Is new subscriber?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
620,
|
||||
-140
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "87fbcc71-a0a4-4820-bb67-9551d44e0500",
|
||||
"operator": {
|
||||
"name": "filter.operator.equals",
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
},
|
||||
"leftValue": "={{ $json.is_first_subscription_payment }}",
|
||||
"rightValue": "true"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "b158a59d-5166-4469-b999-5235768855c0",
|
||||
"name": "Prepare",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
-260,
|
||||
-40
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "aabaa149-d74b-464c-bbb6-12e2e8a884d9",
|
||||
"name": "verificationToken",
|
||||
"type": "string",
|
||||
"value": "7dd9d4ef-8412-4add-a0d0-b548ad4564b9"
|
||||
},
|
||||
{
|
||||
"id": "c2f7a7ce-99b0-44c7-b2cf-1ebf85e0917d",
|
||||
"name": "body",
|
||||
"type": "object",
|
||||
"value": "={{ $json.body.data }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "a4fd9607-6d5b-4fbd-a4ce-53e9960887e0",
|
||||
"name": "Check token",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
-40,
|
||||
-40
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "439af86e-c768-4165-ae64-86cd32a07084",
|
||||
"operator": {
|
||||
"name": "filter.operator.equals",
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
},
|
||||
"leftValue": "={{ $json.body.verification_token }}",
|
||||
"rightValue": "={{ $json.verificationToken }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "6c34228e-434c-4ab3-b0ce-0b5c1721ffc8",
|
||||
"name": "Check type",
|
||||
"type": "n8n-nodes-base.switch",
|
||||
"position": [
|
||||
180,
|
||||
-140
|
||||
],
|
||||
"parameters": {
|
||||
"rules": {
|
||||
"values": [
|
||||
{
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "edd5eaa2-60c7-459a-9846-b952b390b1db",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
},
|
||||
"leftValue": "={{ $json.body.type }}",
|
||||
"rightValue": "Donation"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "0cc7f0bf-4d1b-45a5-88ed-5b84050222f8",
|
||||
"operator": {
|
||||
"name": "filter.operator.equals",
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
},
|
||||
"leftValue": "={{ $json.body.type }}",
|
||||
"rightValue": "Subscription"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "a1b74233-7700-434b-be5c-76129c4cd88c",
|
||||
"operator": {
|
||||
"name": "filter.operator.equals",
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
},
|
||||
"leftValue": "={{ $json.body.type }}",
|
||||
"rightValue": "Shop Order"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 3.2
|
||||
},
|
||||
{
|
||||
"id": "87fd0134-5eb4-4c47-acb5-137f24e819f4",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-300,
|
||||
-140
|
||||
],
|
||||
"parameters": {
|
||||
"color": 6,
|
||||
"width": 200,
|
||||
"height": 260,
|
||||
"content": "### Set verification token\nSet your Ko-fi verification token in this node. Available [here](https://ko-fi.com/manage/webhooks)."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "78ac15cb-1336-424e-a235-6e7a66090b9d",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-520,
|
||||
-140
|
||||
],
|
||||
"parameters": {
|
||||
"color": 6,
|
||||
"width": 200,
|
||||
"height": 260,
|
||||
"content": "### Setup your webhook\nFind your webhook URL in this node and set it [here](https://ko-fi.com/manage/webhooks)."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "30892b66-66fb-4926-b817-e280cbadf5ea",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
360,
|
||||
-520
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 540,
|
||||
"height": 260,
|
||||
"content": "### We received a donation\nDo your thing."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "3b849d93-ffa5-4dfe-8743-d43ca7d06e60",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
360,
|
||||
-240
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 540,
|
||||
"height": 260,
|
||||
"content": "### We received a payment for a subscription\nDo your thing."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "bff1913d-1c18-4447-8448-aa059d7b020f",
|
||||
"name": "Sticky Note4",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
360,
|
||||
40
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 540,
|
||||
"height": 260,
|
||||
"content": "### We received a shop order\nDo your thing."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "07da890d-5cc8-4f51-b0c2-c50831c84a64",
|
||||
"name": "Sticky Note5",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-520,
|
||||
-560
|
||||
],
|
||||
"parameters": {
|
||||
"width": 860,
|
||||
"height": 400,
|
||||
"content": "## Receive and handle Ko-fi payment webhooks \nThis workflow receives [Ko-fi payment webhooks](https://ko-fi.com/manage/webhooks), checks the verification token and then check what kind of payment it is.\n\n### Set up\n1. Edit the `Webhook` node and find your webhook URL.\n2. Go to your [Ko-fi webhooks settings](https://ko-fi.com/manage/webhooks) and set your URL\n3. Get your `verification token` from the same page (under advanced) and set it in the `Prepare` node\n4. Enable your workflow and test it from [Ko-fi webhooks settings](https://ko-fi.com/manage/webhooks)\n5. Profit 🎉\n\n**👋 Hello! I'm Audun / xqus** \n🔗 My work: [xqus.com](https://xqus.com)\n💸 n8n shop: [xqus.gumroad.com](https://xqus.gumroad.com)\n\n### Want to trigger my workflow?\nSupport my work on [Ko-fi](https://ko-fi.com/xquscom) 💸"
|
||||
},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Prepare": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check token",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Prepare",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check type": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Donation",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Subscription",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Shop Order",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check token": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check type",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Subscription": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Is new subscriber?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,587 @@
|
||||
{
|
||||
"meta": {
|
||||
"instanceId": "4a8c4d3ed2f4423694f8ac022d1c321551900c7ab47e0c03549acecec1ab4a89",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"id": "a5292068-5ace-4372-9869-46100ae81b8f",
|
||||
"name": "Get video details",
|
||||
"type": "n8n-nodes-base.youTube",
|
||||
"notes": "Make a call to the YouTube API so that we have the thumbnail for the email and the duration to filter out shorts.",
|
||||
"position": [
|
||||
1000,
|
||||
-60
|
||||
],
|
||||
"parameters": {
|
||||
"part": [
|
||||
"contentDetails",
|
||||
"snippet",
|
||||
"id"
|
||||
],
|
||||
"options": {},
|
||||
"videoId": "={{ $json.id.replace(\"yt:video:\", \"\") }}",
|
||||
"resource": "video",
|
||||
"operation": "get"
|
||||
},
|
||||
"credentials": {
|
||||
"youTubeOAuth2Api": {
|
||||
"id": "5lD8Hahvq4r7Og0F",
|
||||
"name": "YouTube account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "b9eb34aa-90c4-492a-a33e-37a32812fa32",
|
||||
"name": "Schedule Trigger",
|
||||
"type": "n8n-nodes-base.scheduleTrigger",
|
||||
"position": [
|
||||
-840,
|
||||
-160
|
||||
],
|
||||
"parameters": {
|
||||
"rule": {
|
||||
"interval": [
|
||||
{
|
||||
"field": "hours",
|
||||
"hoursInterval": 1,
|
||||
"triggerAtMinute": 47
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "8f0dbe74-53e5-4b14-86f6-eb0f502c8471",
|
||||
"name": "Filter out shorts",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"notes": "Sometime, some live broadcasts that are then posted as regular videos do not have a duration. That is why we check if `duration` is present in `contentDetails`.",
|
||||
"position": [
|
||||
1180,
|
||||
-60
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 1,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "or",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "5342ecc0-d764-4bef-8161-d1f571fcb931",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "notExists",
|
||||
"singleValue": true
|
||||
},
|
||||
"leftValue": "={{ $json.contentDetails.duration }}",
|
||||
"rightValue": "\"duration\""
|
||||
},
|
||||
{
|
||||
"id": "b82e3373-a28b-49bd-afa0-4f48cafe2bfe",
|
||||
"operator": {
|
||||
"type": "number",
|
||||
"operation": "gt"
|
||||
},
|
||||
"leftValue": "={{ Duration.fromISO($json.contentDetails.duration).as('seconds') }}",
|
||||
"rightValue": 61
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"notesInFlow": false,
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "14d54ed0-f5c0-4992-af56-0af2d8973963",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-900,
|
||||
-340
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 220,
|
||||
"height": 460,
|
||||
"content": "### Default frequency: every hour\nChanging it here is enough if you want to check for new videos at a higher or lower frequency. You don't have to edit anything else."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c4acbb10-1f57-4934-a324-f26d0532767c",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-660,
|
||||
-340
|
||||
],
|
||||
"parameters": {
|
||||
"color": 5,
|
||||
"width": 880,
|
||||
"height": 460,
|
||||
"content": "### Get my subscriptions from the YouTube Data v3 API\nYou can expect to use 1 quota per 50 subscriptions per run, which is well within the 10 000/req a day allowed by default."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "4ae2d2f3-53b5-4431-90d8-06e41a6950e2",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
480,
|
||||
-160
|
||||
],
|
||||
"parameters": {
|
||||
"color": 4,
|
||||
"width": 440,
|
||||
"height": 280,
|
||||
"content": "### Get the 15 latest videos of each channel with RSS\nUsing the YouTube API instead would cost too many quotas to make it viable."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "48894d79-7e59-49fc-beb5-445fb5ca2ff6",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
940,
|
||||
-160
|
||||
],
|
||||
"parameters": {
|
||||
"color": 3,
|
||||
"width": 400,
|
||||
"height": 280,
|
||||
"content": "### Call YouTube's API for more data\nWe need the thumbnails for the email and the duration to filter out shorts."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "e3da3f97-138c-481e-a763-9a3c9e402928",
|
||||
"name": "Sticky Note4",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1360,
|
||||
-160
|
||||
],
|
||||
"parameters": {
|
||||
"color": 6,
|
||||
"width": 260,
|
||||
"height": 280,
|
||||
"content": "### Configure your email here\nTo go to the video from the email, simply click on the thumbnail."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "0d092c3d-b2e1-4468-a044-c6cf0f37672b",
|
||||
"name": "Get latest 15 videos of each channel",
|
||||
"type": "n8n-nodes-base.rssFeedRead",
|
||||
"notes": "YouTube provides an RSS feed for each channel with the 15 latest videos.\nWe use this instead of the YouTube Data v3 API, as search requests cost a lot of \"quota points\" and would easily put us over the daily limit with just one workflow run.",
|
||||
"position": [
|
||||
540,
|
||||
-60
|
||||
],
|
||||
"parameters": {
|
||||
"url": "=https://www.youtube.com/feeds/videos.xml?channel_id={{ $json.snippet.resourceId.channelId }}",
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 1.1
|
||||
},
|
||||
{
|
||||
"id": "34823384-d8a5-415a-87ff-203d65aa9a75",
|
||||
"name": "Get my subscriptions",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"notes": "Get subscriptions from YouTube Data v3 API",
|
||||
"position": [
|
||||
-600,
|
||||
-160
|
||||
],
|
||||
"parameters": {
|
||||
"url": "https://www.googleapis.com/youtube/v3/subscriptions",
|
||||
"options": {
|
||||
"pagination": {
|
||||
"pagination": {
|
||||
"parameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "pageToken",
|
||||
"value": "={{ $response.body.nextPageToken }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"completeExpression": "={{ !('nextPageToken' in $response.body) }}",
|
||||
"paginationCompleteWhen": "other"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sendQuery": true,
|
||||
"authentication": "predefinedCredentialType",
|
||||
"queryParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "mine",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "part",
|
||||
"value": "snippet,contentDetails"
|
||||
},
|
||||
{
|
||||
"name": "maxResults",
|
||||
"value": "50"
|
||||
}
|
||||
]
|
||||
},
|
||||
"nodeCredentialType": "youTubeOAuth2Api"
|
||||
},
|
||||
"credentials": {
|
||||
"youTubeOAuth2Api": {
|
||||
"id": "5lD8Hahvq4r7Og0F",
|
||||
"name": "YouTube account"
|
||||
}
|
||||
},
|
||||
"notesInFlow": true,
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "534e38f3-ac40-4194-8821-5926ee581605",
|
||||
"name": "Check for errors",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
-400,
|
||||
-160
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "5972ff90-aa5a-470c-aa96-87138eb60565",
|
||||
"operator": {
|
||||
"type": "object",
|
||||
"operation": "exists",
|
||||
"singleValue": true
|
||||
},
|
||||
"leftValue": "={{ $json.error }}",
|
||||
"rightValue": "error"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "2d872c0f-30b9-4ffc-aba0-6644bf05d7bb",
|
||||
"name": "Only keep channels with unwatched videos",
|
||||
"type": "n8n-nodes-base.filter",
|
||||
"notes": "It's not a perfect indicator for new videos but helps reduce the amount of channels to process.",
|
||||
"position": [
|
||||
40,
|
||||
-60
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "4734ee8c-1655-47be-bd45-a9527aee2833",
|
||||
"operator": {
|
||||
"type": "number",
|
||||
"operation": "gt"
|
||||
},
|
||||
"leftValue": "={{ $json.contentDetails.newItemCount }}",
|
||||
"rightValue": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "c7bd97ec-47c1-40b4-955d-bf89d3cde330",
|
||||
"name": "Keep only videos published since last run",
|
||||
"type": "n8n-nodes-base.filter",
|
||||
"notes": "We dynamically figure out the last run's execution time through the settings of the \"Schedule Trigger\" node.",
|
||||
"position": [
|
||||
740,
|
||||
-60
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "65d905a2-c89e-41f3-a2cf-0d1a76c48d8e",
|
||||
"operator": {
|
||||
"type": "dateTime",
|
||||
"operation": "after"
|
||||
},
|
||||
"leftValue": "={{ $json.pubDate.toDateTime() }}",
|
||||
"rightValue": "={{ \n $('Schedule Trigger').item.json.timestamp.toDateTime().minus(\n $('Schedule Trigger').params.rule.interval[0].hoursInterval,\n $('Schedule Trigger').params.rule.interval[0].field\n ).toISO()\n}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "72341b1f-a391-4210-b3ca-4e74ae1f2e1b",
|
||||
"name": "Send an email for each new video",
|
||||
"type": "n8n-nodes-base.emailSend",
|
||||
"notes": "The expression in the HTML for the thumbnail simply selects the last element of the thumbnails array so that we get the best possible resolution thumbnail available.",
|
||||
"position": [
|
||||
1440,
|
||||
-60
|
||||
],
|
||||
"webhookId": "44bf0e95-98e5-4b5b-a7c5-c802379ab3b0",
|
||||
"parameters": {
|
||||
"html": "=<h1 style=\"text-align: center;\">{{ $json.snippet.title }}</h1>\n<a href=\"https://www.youtube.com/watch?v={{ $json.id }}\">\n <img src=\"{{ $json.snippet.thumbnails[Object.keys($json.snippet.thumbnails)[Object.keys($json.snippet.thumbnails).length - 1]].url }}\" alt=\"Watch on YouTube\" style=\"width:100%; height:auto; max-width:640px; display:block; margin: 10px auto;\">\n</a>",
|
||||
"options": {
|
||||
"appendAttribution": false
|
||||
},
|
||||
"subject": "={{ $json.snippet.channelTitle }}",
|
||||
"toEmail": "My Name <to@email.com>",
|
||||
"fromEmail": "YouTube <from@email.com>"
|
||||
},
|
||||
"credentials": {
|
||||
"smtp": {
|
||||
"id": "ThrKm6bLUg1owKn1",
|
||||
"name": "SMTP account"
|
||||
}
|
||||
},
|
||||
"notesInFlow": false,
|
||||
"typeVersion": 2.1
|
||||
},
|
||||
{
|
||||
"id": "b82cfbd5-71e3-418f-9b6d-6d0ec007733a",
|
||||
"name": "If the HTTP request failed, throw the error",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
-180,
|
||||
-260
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "=Status code: {{ $json.error.code }}\nMessage: {{ $json.error.message }}"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "e89eca92-896f-46b5-8a4b-149d51682faa",
|
||||
"name": "Split out subscriptions to process individually",
|
||||
"type": "n8n-nodes-base.splitOut",
|
||||
"position": [
|
||||
-180,
|
||||
-60
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"fieldToSplitOut": "items"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "0e00fda6-1489-4c1a-8205-22e620a554c5",
|
||||
"name": "Sticky Note5",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
240,
|
||||
-240
|
||||
],
|
||||
"parameters": {
|
||||
"width": 220,
|
||||
"height": 360,
|
||||
"content": "## Manually filter out channels\nTo find the channel ID of a channel, click on the description → Share channel → Copy channel ID"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "bcc2e57c-23b2-42b7-81ab-cdd88b70b8a3",
|
||||
"name": "Filter out channels",
|
||||
"type": "n8n-nodes-base.filter",
|
||||
"notes": "Optional step",
|
||||
"position": [
|
||||
300,
|
||||
-60
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "b27b14a9-c86c-4ebd-8a0f-4e7db722796e",
|
||||
"operator": {
|
||||
"type": "array",
|
||||
"operation": "notContains",
|
||||
"rightType": "any"
|
||||
},
|
||||
"leftValue": "={{[\n \"exampleChannelId1\",\n \"exampleChannelId2\"\n]}}",
|
||||
"rightValue": "={{ $json.snippet.resourceId.channelId }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"notesInFlow": true,
|
||||
"typeVersion": 2.2
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Check for errors": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "If the HTTP request failed, throw the error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Split out subscriptions to process individually",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Schedule Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get my subscriptions",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Filter out shorts": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send an email for each new video",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[]
|
||||
]
|
||||
},
|
||||
"Get video details": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Filter out shorts",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Filter out channels": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get latest 15 videos of each channel",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get my subscriptions": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check for errors",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Send an email for each new video": {
|
||||
"main": [
|
||||
[]
|
||||
]
|
||||
},
|
||||
"Get latest 15 videos of each channel": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Keep only videos published since last run",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Only keep channels with unwatched videos": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Filter out channels",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Keep only videos published since last run": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get video details",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Split out subscriptions to process individually": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Only keep channels with unwatched videos",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,576 @@
|
||||
{
|
||||
"id": "5Ycrm1MuK8htwd96",
|
||||
"meta": {
|
||||
"instanceId": "e5595d8cd58f3a24b5a8cf05dd852846c05423873db868a2b7d01a778210c45a",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"name": "Telegram RAG pdf",
|
||||
"tags": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "9fbce801-8c42-43a4-bc70-d93042d68b2c",
|
||||
"name": "Telegram Trigger",
|
||||
"type": "n8n-nodes-base.telegramTrigger",
|
||||
"position": [
|
||||
-220,
|
||||
240
|
||||
],
|
||||
"webhookId": "b178f034-9997-4832-9bb4-a43c3015506e",
|
||||
"parameters": {
|
||||
"updates": [
|
||||
"message"
|
||||
],
|
||||
"additionalFields": {}
|
||||
},
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.1
|
||||
},
|
||||
{
|
||||
"id": "1bfc1fbd-86b1-4a8a-9301-fe54497f5acd",
|
||||
"name": "Embeddings OpenAI",
|
||||
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
|
||||
"position": [
|
||||
720,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"credentials": {
|
||||
"openAiApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "d5ad7851-ed40-4b3a-b0d5-aeaf04362f1c",
|
||||
"name": "Default Data Loader",
|
||||
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
|
||||
"position": [
|
||||
860,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"dataType": "binary"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "fed803d0-49a2-4b82-8f20-a02a10caa027",
|
||||
"name": "Recursive Character Text Splitter",
|
||||
"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
|
||||
"position": [
|
||||
940,
|
||||
680
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"chunkSize": 3000,
|
||||
"chunkOverlap": 200
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "ab60f36f-fada-4812-8dbd-441ad372cb80",
|
||||
"name": "Stop and Error",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
220,
|
||||
840
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "An error occurred"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c87f1db3-7cc9-4063-9895-4b4d68ea53a1",
|
||||
"name": "Question and Answer Chain",
|
||||
"type": "@n8n/n8n-nodes-langchain.chainRetrievalQa",
|
||||
"position": [
|
||||
-280,
|
||||
500
|
||||
],
|
||||
"parameters": {
|
||||
"text": "={{ $json.message.text }}\nSearch the database with the retriever for information for the answer",
|
||||
"promptType": "define"
|
||||
},
|
||||
"typeVersion": 1.3
|
||||
},
|
||||
{
|
||||
"id": "c9bc4c80-8e57-48bc-a405-131ed7348c1d",
|
||||
"name": "Vector Store Retriever",
|
||||
"type": "@n8n/n8n-nodes-langchain.retrieverVectorStore",
|
||||
"position": [
|
||||
-240,
|
||||
680
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "0217056f-2b71-4308-adf1-19dcd4d2cc11",
|
||||
"name": "Pinecone Vector Store1",
|
||||
"type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
|
||||
"position": [
|
||||
-280,
|
||||
860
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"pineconeIndex": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": "telegram",
|
||||
"cachedResultName": "telegram"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"pineconeApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "693f9026-f47f-48dc-8e5d-e8b832a37235",
|
||||
"name": "Groq Chat Model",
|
||||
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
|
||||
"position": [
|
||||
-380,
|
||||
660
|
||||
],
|
||||
"parameters": {
|
||||
"model": "llama-3.1-70b-versatile",
|
||||
"options": {}
|
||||
},
|
||||
"credentials": {
|
||||
"groqApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c7acf014-138f-4be7-b569-c309bb10e50d",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
500,
|
||||
73.04879287725316
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 1139.5159692915001,
|
||||
"height": 873.6068151028411,
|
||||
"content": "# Load data into database\nFetch file from **Telegram**, split it into chunks and insert into **Pinecone** index, a message from **Telegram** will be sent just to let the user know that the process finished"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "dd3b9d8b-5771-4a09-8c1b-794cb8737d5d",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-878.769,
|
||||
400
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 1344.7918019808176,
|
||||
"height": 806.8716167324012,
|
||||
"content": "# Chat with Database\n\n1. **Receive** the incoming chat message.\n2. **Retrieve** relevant chunks from the _vector store_.\n3. **Pass** these chunks to the model.\n\nThe model will use the retrieved information to **formulate a precise response**.\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "9aaf575a-5e40-407c-951c-10b1d16e5d3c",
|
||||
"name": "Check If is a document",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
220,
|
||||
240
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "8839993b-9fe7-4e1e-a1cc-fe5de6b0bb62",
|
||||
"operator": {
|
||||
"type": "object",
|
||||
"operation": "exists",
|
||||
"singleValue": true
|
||||
},
|
||||
"leftValue": "={{ $json.message.document }}",
|
||||
"rightValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "c1edb6bf-ba95-4a5f-9626-add673274086",
|
||||
"name": "Change to application/pdf",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
700,
|
||||
220
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "// Função para modificar os metadados do arquivo binário\nfunction modifyBinaryMetadata(items) {\n for (const item of items) {\n if (item.binary && item.binary.data) {\n // Modifica o tipo MIME\n item.binary.data.mimeType = 'application/pdf';\n \n // Garante que o nome do arquivo termine com .pdf\n if (!item.binary.data.fileName.toLowerCase().endsWith('.pdf')) {\n item.binary.data.fileName += '.pdf';\n }\n \n // Atualiza o contentType no fileType (se existir)\n if (item.binary.data.fileType) {\n item.binary.data.fileType.contentType = 'application/pdf';\n }\n }\n }\n return items;\n}\n\n// Aplica a modificação e retorna os itens atualizados\nreturn modifyBinaryMetadata($input.all());"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "ea4d4e74-8954-47f0-a3a0-662d47ea2298",
|
||||
"name": "Telegram get File",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"position": [
|
||||
520,
|
||||
220
|
||||
],
|
||||
"parameters": {
|
||||
"fileId": "={{ $json.message.document.file_id }}",
|
||||
"resource": "file"
|
||||
},
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "cf548bee-d5d5-4f1a-a059-932ea163e155",
|
||||
"name": "Embeddings",
|
||||
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
|
||||
"position": [
|
||||
-100,
|
||||
1080
|
||||
],
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"credentials": {
|
||||
"openAiApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "e3bd4759-80cc-42bb-ba53-f9e88e9ba916",
|
||||
"name": "Telegram Response",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"onError": "continueErrorOutput",
|
||||
"position": [
|
||||
160,
|
||||
560
|
||||
],
|
||||
"parameters": {
|
||||
"text": "={{ $json.response.text }}",
|
||||
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "e478df48-9e6d-4a84-89be-beb569914ae3",
|
||||
"name": "Telegram Response about Database",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"onError": "continueErrorOutput",
|
||||
"position": [
|
||||
1400,
|
||||
220
|
||||
],
|
||||
"parameters": {
|
||||
"text": "={{ $json.metadata.pdf.totalPages }} pages saved on Pinecone",
|
||||
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "5be7a321-1be6-4173-83de-3d569666718d",
|
||||
"name": "Stop and Error1",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
1400,
|
||||
580
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "An error occurred."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "aae26861-f34d-4b59-bd99-3662fbd6676c",
|
||||
"name": "Pinecone Vector Store",
|
||||
"type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
|
||||
"position": [
|
||||
880,
|
||||
220
|
||||
],
|
||||
"parameters": {
|
||||
"mode": "insert",
|
||||
"options": {},
|
||||
"pineconeIndex": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": "telegram",
|
||||
"cachedResultName": "telegram"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"pineconeApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "312fb807-4225-4630-ab32-aa12fe07c127",
|
||||
"name": "Limit to 1",
|
||||
"type": "n8n-nodes-base.limit",
|
||||
"position": [
|
||||
1220,
|
||||
220
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"active": true,
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"timezone": "America/Sao_Paulo",
|
||||
"callerPolicy": "workflowsFromSameOwner",
|
||||
"executionOrder": "v1",
|
||||
"saveManualExecutions": true
|
||||
},
|
||||
"versionId": "03612d23-6630-4ec6-8738-1dae593c8d23",
|
||||
"connections": {
|
||||
"Embeddings": {
|
||||
"ai_embedding": [
|
||||
[
|
||||
{
|
||||
"node": "Pinecone Vector Store1",
|
||||
"type": "ai_embedding",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Limit to 1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram Response about Database",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Groq Chat Model": {
|
||||
"ai_languageModel": [
|
||||
[
|
||||
{
|
||||
"node": "Question and Answer Chain",
|
||||
"type": "ai_languageModel",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Telegram Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check If is a document",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Embeddings OpenAI": {
|
||||
"ai_embedding": [
|
||||
[
|
||||
{
|
||||
"node": "Pinecone Vector Store",
|
||||
"type": "ai_embedding",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Telegram Response": {
|
||||
"main": [
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Telegram get File": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Change to application/pdf",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Default Data Loader": {
|
||||
"ai_document": [
|
||||
[
|
||||
{
|
||||
"node": "Pinecone Vector Store",
|
||||
"type": "ai_document",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Pinecone Vector Store": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Limit to 1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check If is a document": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram get File",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Question and Answer Chain",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Pinecone 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
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Change to application/pdf": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Pinecone Vector Store",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Question and Answer Chain": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram Response",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Telegram Response about Database": {
|
||||
"main": [
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Recursive Character Text Splitter": {
|
||||
"ai_textSplitter": [
|
||||
[
|
||||
{
|
||||
"node": "Default Data Loader",
|
||||
"type": "ai_textSplitter",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
{
|
||||
"id": "84dT8cFL0FV8ZGPx",
|
||||
"meta": {
|
||||
"instanceId": "85d2d2ffc8886227640b031e8f18fdfe6c91f530d34ec1a8b1f13727419ae956"
|
||||
},
|
||||
"name": "Slack Webhook - Verify Signature",
|
||||
"tags": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "b12fe8e7-45c4-4021-826e-3ae430e34001",
|
||||
"name": "Make Slack Verif Token",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
900,
|
||||
400
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "function encodeFormData(data) {\n const encodedData = Object.keys(data)\n .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))\n .join('&')\n .replaceAll(\"%20\", \"+\") // Slack does not encode \"+\" signs\n .replaceAll(\"*\", \"%2A\") // Slack encodes \"*\" signs\n .replaceAll(\"~\", \"%7E\"); // Slack encodes \"~\" signs\n \n return encodedData;\n}\n\nfunction buildSigBaseString(requestJson) {\n const version = \"v0\"; // Slack Webhook version (Always v0 for the moment)\n \n const timestamp = requestJson.headers[\"x-slack-request-timestamp\"];\n \n const body = requestJson.body;\n const encodedBody = encodeFormData(body);\n \n const sigBaseString = `${version}:${timestamp}:${encodedBody}`;\n\n return sigBaseString;\n}\n\nconst requestJson = $input.first().json;\n\nconst sigBaseString = buildSigBaseString(requestJson);\n\nconst requestSignature = requestJson.headers[\"x-slack-signature\"];\n\nconsole.log({\n sigBaseString,\n requestSignature\n });\nreturn {\n json: {\n sigBaseString,\n requestSignature\n },\n pairedItem: 0\n}\n\n\n"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "a91e2d8f-e907-439c-9fd3-cb75e957b059",
|
||||
"name": "Encode Secret String",
|
||||
"type": "n8n-nodes-base.crypto",
|
||||
"position": [
|
||||
1120,
|
||||
400
|
||||
],
|
||||
"parameters": {
|
||||
"type": "SHA256",
|
||||
"value": "={{ $json.sigBaseString }}",
|
||||
"action": "hmac",
|
||||
"dataPropertyName": "candidateSignature"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "d79ccfe1-61cd-4da4-bfff-1e504627bb3d",
|
||||
"name": "IF",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
1360,
|
||||
400
|
||||
],
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"string": [
|
||||
{
|
||||
"value1": "={{ $json.requestSignature }}",
|
||||
"value2": "=v0={{ $json.candidateSignature }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "cb2b9908-c226-438b-adb2-7c1ec852e007",
|
||||
"name": "Stop and Error",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
1580,
|
||||
580
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "Could not verify Slack Webhook signature"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "5ef4c06a-717b-4f90-83a7-06eda780a892",
|
||||
"name": "Execute Workflow Trigger",
|
||||
"type": "n8n-nodes-base.executeWorkflowTrigger",
|
||||
"position": [
|
||||
680,
|
||||
400
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "86b022fb-63fd-4ccf-952e-19ed0da54a5c",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
880,
|
||||
-420
|
||||
],
|
||||
"parameters": {
|
||||
"color": 4,
|
||||
"width": 554.4117841902089,
|
||||
"height": 278.2403290971726,
|
||||
"content": "## Slack Webhook - Verify Signature \nWhen receiving a message from a Slack Webhook, it is much more secure to verify that the message comes from Slack and not from bots or unknown services.\n\nThis small template is designed to validate the received signature (See [this URL](https://api.slack.com/authentication/verifying-requests-from-slack)).\n\n### Colors\n- **Blue** areas are **areas to edit**\n- **Yellow** areas are **explanations**"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "f5af4f44-1ea5-419b-a58b-f8f6839b6b05",
|
||||
"name": "Set Verified to True",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
1580,
|
||||
220
|
||||
],
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "signature_verified",
|
||||
"type": "booleanValue"
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": "none",
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 3.2
|
||||
},
|
||||
{
|
||||
"id": "8a76dec8-7a2d-4cc9-82c9-002141e205ec",
|
||||
"name": "Merge",
|
||||
"type": "n8n-nodes-base.merge",
|
||||
"position": [
|
||||
1920,
|
||||
40
|
||||
],
|
||||
"parameters": {
|
||||
"mode": "combine",
|
||||
"options": {},
|
||||
"combinationMode": "mergeByPosition"
|
||||
},
|
||||
"typeVersion": 2.1
|
||||
},
|
||||
{
|
||||
"id": "0c8506bc-b114-4d25-8586-80549ae0026d",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1000,
|
||||
40
|
||||
],
|
||||
"parameters": {
|
||||
"color": 6,
|
||||
"width": 359.58396920054975,
|
||||
"height": 548.3119898759418,
|
||||
"content": "## TO EDIT \nSet your Slack Signing Secret.\nYou can obtain it by visiting your Slack App dashboard in the general tab: https://api.slack.com/apps/[SLACK_APP_ID]/general\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "20cca69c-9d00-4471-8845-2cb91458c23e",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1560,
|
||||
399
|
||||
],
|
||||
"parameters": {
|
||||
"width": 300.4638046519632,
|
||||
"height": 360.20237540316725,
|
||||
"content": "## Error Output\nIf the signature cannot be verified, an error will be raised. You can manage this scenario in your main workflow by either using an Error Workflow or by modifying your node settings and selecting appropriate actions in the event of an error.\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "55ede23b-acb4-43ea-ac32-c678dd48e056",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1880,
|
||||
-220
|
||||
],
|
||||
"parameters": {
|
||||
"width": 300.4638046519632,
|
||||
"height": 427.3843805720155,
|
||||
"content": "## Success Output\nIf the signature is successfully verified, we return a key `verified_signature` set to `true` along with the data from the Slack request itself.\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "22d44888-5af4-43b9-b514-ebfc9c61b07c",
|
||||
"name": "Sticky Note4",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
560,
|
||||
160
|
||||
],
|
||||
"parameters": {
|
||||
"width": 300.4638046519632,
|
||||
"height": 427.3843805720155,
|
||||
"content": "## Input\nThe input should be the received Slack request. Place this workflow directly after the Slack Webhook.\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"active": false,
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "f9e78d89-0da8-465e-aa47-5396d9ac4d48",
|
||||
"connections": {
|
||||
"IF": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set Verified to True",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Encode Secret String": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "IF",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set Verified to True": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Merge",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Make Slack Verif Token": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Encode Secret String",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Workflow Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Make Slack Verif Token",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Merge",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,423 @@
|
||||
{
|
||||
"id": "AS2Rj41p6OyA0xZK",
|
||||
"meta": {
|
||||
"instanceId": "7858a8e25b8fc4dae485c1ef345e6fe74effb1f5060433ef500b4c186c965c18",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"name": "Auth0 User Login",
|
||||
"tags": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "25022573-c99e-40d2-88e2-a0e7a9780181",
|
||||
"name": "Request Access Token",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
1260,
|
||||
320
|
||||
],
|
||||
"parameters": {
|
||||
"url": "={{ $json.domain }}/oauth/token",
|
||||
"method": "POST",
|
||||
"options": {},
|
||||
"jsonBody": "={\n \"grant_type\": \"authorization_code\",\n \"code\": \"{{ $json.query.code }}\",\n \"client_id\": \"{{ $json.client_id }}\",\n \"client_secret\": \"{{ $json.client_secret }}\",\n \"redirect_uri\": \"{{ $json.my_server }}\",\n \"audience\": \"{{ $json.domain }}/api/v2/\"\n}",
|
||||
"sendBody": true,
|
||||
"sendHeaders": true,
|
||||
"specifyBody": "json",
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/x-www-form-urlencoded"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "233d69ed-d835-4022-815e-e786706ec78a",
|
||||
"name": "Get Userinfo",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
1500,
|
||||
320
|
||||
],
|
||||
"parameters": {
|
||||
"url": "={{ $('Set Application Details1').item.json.domain }}/userinfo",
|
||||
"options": {},
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "=Bearer {{ $json.access_token }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "860e8a20-f6a3-4c8e-be71-361e6f1f8641",
|
||||
"name": "If",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
720,
|
||||
320
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "fa80ac35-7029-4507-b5ea-845bec07b672",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "exists",
|
||||
"singleValue": true
|
||||
},
|
||||
"leftValue": "={{$json.query.code}}",
|
||||
"rightValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.1
|
||||
},
|
||||
{
|
||||
"id": "7c4e15c7-2ee0-4c54-8255-e7cc250e718a",
|
||||
"name": "No Code Found",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
880,
|
||||
540
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "Couldn't get authorization code!"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "2e0b2ff5-47ce-4199-bdd2-e31a4d32fd15",
|
||||
"name": "Open Auth Webpage",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"position": [
|
||||
1020,
|
||||
40
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"redirectURL": "={{ $json.domain }}/authorize?response_type=code&scope=openid+email+profile+image+name&client_id={{ $json.client_id }}&redirect_uri={{ $json.my_server }}/webhook/receive-token",
|
||||
"respondWith": "redirect"
|
||||
},
|
||||
"typeVersion": 1.1
|
||||
},
|
||||
{
|
||||
"id": "d790ce47-725a-4a69-b66f-f7e80e2d9e5e",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1180,
|
||||
80
|
||||
],
|
||||
"parameters": {
|
||||
"color": 6,
|
||||
"width": 238.05017098334866,
|
||||
"height": 140.50170983348636,
|
||||
"content": "### You can also add &connection=github to end of authorize URL in order to get user to login via Github, Facebook, etc"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "1c5bb01a-0fed-4783-b18d-d8f7e818371c",
|
||||
"name": "Set Application Details",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
780,
|
||||
40
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "003d523a-5e14-4a5a-aed6-f72c3fce6e6d",
|
||||
"name": "domain",
|
||||
"type": "string",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"id": "7db513f3-55f6-4bab-92b0-e62d0b7f05a1",
|
||||
"name": "client_id",
|
||||
"type": "string",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"id": "52da7d5d-6683-4cf9-a7de-c2ab2ce48f3d",
|
||||
"name": "my_server",
|
||||
"type": "string",
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"includeOtherFields": true
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "8ced9fb6-fd49-4d57-8d74-b04e45b6c216",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
80,
|
||||
-456.1003419666973
|
||||
],
|
||||
"parameters": {
|
||||
"color": 5,
|
||||
"width": 623.7263504769883,
|
||||
"height": 397.87914003146636,
|
||||
"content": "## 1. First, go to https://auth0.com and create a Single Page Application. From Dashboard/Applications, click on your new app settings. The first step is to add the following to allowed callback URLs:\nhttp://localhost:5678, http://localhost:5678/webhook/receive-token \n\n### (If you do not run n8n locally, replace localhost with your server where you run n8n. You must also replace it in **Set Application Details** 'my_server' field)\n\n## From the same settings page, retrieve the Domain, Client_ID, and Client_Secret of your application."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "94155312-1230-4c13-9104-5e26a6f68e91",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1280,
|
||||
-40
|
||||
],
|
||||
"parameters": {
|
||||
"color": 6,
|
||||
"width": 437.4336297478876,
|
||||
"height": 107.35461655041311,
|
||||
"content": "### This step will return the authentication page to the user and let him login using gmail or by creating a new account."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "9a7bcabf-1cc0-43e5-8f52-cc3f2781150f",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
420,
|
||||
-40
|
||||
],
|
||||
"parameters": {
|
||||
"width": 1296.8510714753793,
|
||||
"height": 256.53228919365705,
|
||||
"content": "## Step 1: Authentication\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "7e7560d6-4c26-4e80-ad62-07a674e928f9",
|
||||
"name": "Sticky Note4",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
420,
|
||||
260
|
||||
],
|
||||
"parameters": {
|
||||
"width": 1302.371850917427,
|
||||
"height": 444.78164181462137,
|
||||
"content": "## Step 2: Get Access Token\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "97c8bc77-bc7d-4be2-9858-668c5e325f49",
|
||||
"name": "Sticky Note5",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
420,
|
||||
560.9464093496792
|
||||
],
|
||||
"parameters": {
|
||||
"color": 6,
|
||||
"width": 327.74230574931124,
|
||||
"height": 144.40136786678917,
|
||||
"content": "### If Step 1 was successful, Auth0 will automatically call Step 2 in its callback with a code. This code is used to generate an access token which can verify the user is legitimate and email verified."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "fe103ba1-8143-482c-846f-0f381ca2661a",
|
||||
"name": "Set Application Details1",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
1000,
|
||||
320
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "003d523a-5e14-4a5a-aed6-f72c3fce6e6d",
|
||||
"name": "domain",
|
||||
"type": "string",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"id": "7db513f3-55f6-4bab-92b0-e62d0b7f05a1",
|
||||
"name": "client_id",
|
||||
"type": "string",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"id": "52da7d5d-6683-4cf9-a7de-c2ab2ce48f3d",
|
||||
"name": "my_server",
|
||||
"type": "string",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"id": "d339dd3d-ed57-4b0f-81c6-a8f5f7c474fb",
|
||||
"name": "client_secret",
|
||||
"type": "string",
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"includeOtherFields": true
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "b3bb59b8-16fc-483d-ae8d-ec3e65c3326d",
|
||||
"name": "/login",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"position": [
|
||||
540,
|
||||
40
|
||||
],
|
||||
"webhookId": "046e2370-0ae1-4d64-be9b-cbb0545de323",
|
||||
"parameters": {
|
||||
"path": "login",
|
||||
"options": {},
|
||||
"responseMode": "responseNode"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "79825832-6d06-4a48-aa0a-bad3d52ab2c1",
|
||||
"name": "/receive-token",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"position": [
|
||||
540,
|
||||
320
|
||||
],
|
||||
"webhookId": "7bd9ea5a-c354-41c0-9d17-4a02ca8e3055",
|
||||
"parameters": {
|
||||
"path": "receive-token",
|
||||
"options": {},
|
||||
"responseMode": "lastNode"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "b9406ef0-3567-46da-9989-d7f458ad73fb",
|
||||
"name": "Sticky Note7",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
760,
|
||||
-460
|
||||
],
|
||||
"parameters": {
|
||||
"color": 5,
|
||||
"width": 426.62126002791706,
|
||||
"height": 393.48225931142105,
|
||||
"content": "## 2. Fill in Set Application Details and Set Application Details1\n\n## 3. **Login from https://<n8n server address>/webhook/login!**"
|
||||
},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"active": true,
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "7d2f0dad-3951-49e2-9467-03124dbc52ba",
|
||||
"connections": {
|
||||
"If": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set Application Details1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "No Code Found",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"/login": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set Application Details",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"/receive-token": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "If",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Request Access Token": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get Userinfo",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set Application Details": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Open Auth Webpage",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set Application Details1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Request Access Token",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,503 @@
|
||||
{
|
||||
"id": "QyMyf3zraY0wxXDf",
|
||||
"meta": {
|
||||
"instanceId": "ba3fa76a571c35110ef5f67e5099c9a5c1768ef125c2f3b804ba20de75248c0b",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"name": "Load Prompts from Github Repo and auto populate n8n expressions",
|
||||
"tags": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "34781446-b06e-41eb-83b8-b96bda1a5595",
|
||||
"name": "When clicking \u2018Test workflow\u2019",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"position": [
|
||||
-80,
|
||||
0
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c53b7243-7c82-47e0-a5ee-bd82bc51c386",
|
||||
"name": "GitHub",
|
||||
"type": "n8n-nodes-base.github",
|
||||
"position": [
|
||||
600,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"owner": {
|
||||
"__rl": true,
|
||||
"mode": "name",
|
||||
"value": "={{ $json.Account }}"
|
||||
},
|
||||
"filePath": "={{ $json.path }}{{ $json.prompt }}",
|
||||
"resource": "file",
|
||||
"operation": "get",
|
||||
"repository": {
|
||||
"__rl": true,
|
||||
"mode": "name",
|
||||
"value": "={{ $json.repo }}"
|
||||
},
|
||||
"additionalParameters": {}
|
||||
},
|
||||
"credentials": {
|
||||
"githubApi": {
|
||||
"id": "ostHZNoe8GSsbaQM",
|
||||
"name": "The GitHub account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "9976b199-b744-47a7-9d75-4b831274c01b",
|
||||
"name": "Extract from File",
|
||||
"type": "n8n-nodes-base.extractFromFile",
|
||||
"position": [
|
||||
840,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"operation": "text"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "26aa4e6a-c487-4cdf-91d5-df660cf826a6",
|
||||
"name": "setVars",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
180,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "150618c5-09b1-4f8b-a7b4-984662bf3381",
|
||||
"name": "Account",
|
||||
"type": "string",
|
||||
"value": "TPGLLC-US"
|
||||
},
|
||||
{
|
||||
"id": "22e8a3b0-bd53-485c-b971-7f1dd0686f0e",
|
||||
"name": "repo",
|
||||
"type": "string",
|
||||
"value": "PeresPrompts"
|
||||
},
|
||||
{
|
||||
"id": "ab94d0a1-ef3a-4fe9-9076-6882c6fda0ac",
|
||||
"name": "path",
|
||||
"type": "string",
|
||||
"value": "SEO/"
|
||||
},
|
||||
{
|
||||
"id": "66f122eb-1cbd-4769-aac8-3f05cdb6c116",
|
||||
"name": "prompt",
|
||||
"type": "string",
|
||||
"value": "keyword_research.md"
|
||||
},
|
||||
{
|
||||
"id": "03fe26a3-04e6-439c-abcb-d438fc5203c0",
|
||||
"name": "company",
|
||||
"type": "string",
|
||||
"value": "South Nassau Physical Therapy"
|
||||
},
|
||||
{
|
||||
"id": "c133d216-a457-4872-a060-0ba4d94549af",
|
||||
"name": "product",
|
||||
"type": "string",
|
||||
"value": "Manual Therapy"
|
||||
},
|
||||
{
|
||||
"id": "584864dd-2518-45e2-b501-02828757fc3a",
|
||||
"name": "features",
|
||||
"type": "string",
|
||||
"value": "pain relief"
|
||||
},
|
||||
{
|
||||
"id": "0c4594cc-302a-4215-bdad-12cf54f57967",
|
||||
"name": "sector",
|
||||
"type": "string",
|
||||
"value": "physical therapy"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "9d92f581-8cd9-448c-aa1d-023a96c1ddda",
|
||||
"name": "replace variables",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
1900,
|
||||
-20
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "// Fetch the prompt text\nconst prompt = $('SetPrompt').first().json.data; // Ensure the prompt contains placeholders like {{ some.node.value }}\n\n// Example variables object\nconst variables = {\n company: $('setVars').first().json.company,\n features: \"Awesome Software\",\n keyword: \"2025-02-07\"\n};\n\n// Function to replace placeholders dynamically\nconst replaceVariables = (text, vars) => {\n return text.replace(/{{(.*?)}}/g, (match, key) => {\n const trimmedKey = key.trim();\n \n // Extract last part after the last dot\n const finalKey = trimmedKey.split('.').pop();\n\n // Replace if key exists, otherwise leave placeholder unchanged\n return vars.hasOwnProperty(finalKey) ? vars[finalKey] : match;\n });\n};\n\n// Replace and return result\nreturn [{\n prompt: replaceVariables(prompt, variables)\n}];\n"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "6c6c4fde-6ee5-47a8-894d-44d1afcedc2a",
|
||||
"name": "If",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
1560,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "2717a7e5-095a-42bf-8b5b-8050c3389ec5",
|
||||
"operator": {
|
||||
"type": "boolean",
|
||||
"operation": "true",
|
||||
"singleValue": true
|
||||
},
|
||||
"leftValue": "={{ $json.success }}",
|
||||
"rightValue": "={{ $('Check All Prompt Vars Present').item.json.keys()}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "3b7712b8-5152-4f60-9401-03c89c39e227",
|
||||
"name": "Check All Prompt Vars Present",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
1280,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "// Get prompt text\nconst prompt = $json.data;\n\n// Extract variables inside {{ }} dynamically\nconst matches = [...prompt.matchAll(/{{(.*?)}}/g)];\nconst uniqueVars = [...new Set(matches.map(match => match[1].trim().split('.').pop()))];\n\n// Get variables from the Set Node\nconst setNodeVariables = $node[\"setVars\"].json || {};\n\n// Log extracted variables and Set Node keys\nconsole.log(\"Extracted Variables:\", uniqueVars);\nconsole.log(\"Set Node Keys:\", Object.keys(setNodeVariables));\n\n// Check if all required variables are present in the Set Node\nconst missingKeys = uniqueVars.filter(varName => !setNodeVariables.hasOwnProperty(varName));\n\nconsole.log(\"Missing Keys:\", missingKeys);\n\n// Return false if any required variable is missing, otherwise return true\nreturn [{\n success: missingKeys.length === 0,\n missingKeys: missingKeys\n}];\n"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "32618e10-3285-4c16-9e78-058dde329337",
|
||||
"name": "SetPrompt",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
1060,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "335b450d-542a-4714-83d8-ccc237188fc5",
|
||||
"name": "data",
|
||||
"type": "string",
|
||||
"value": "={{ $json.data }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "4d8b34ca-50dd-4f37-b4f7-542291461662",
|
||||
"name": "Stop and Error",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
1900,
|
||||
200
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "=Missing Prompt Variables : {{ $('Check All Prompt Vars Present').item.json.missingKeys }}\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "a78c1e17-9152-4241-bcdf-c0d723da543b",
|
||||
"name": "Set Completed Prompt",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
2220,
|
||||
-20
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "57a9625b-adea-4ee7-a72a-2be8db15f3d4",
|
||||
"name": "Prompt",
|
||||
"type": "string",
|
||||
"value": "={{ $json.prompt }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "51447c90-a222-4172-a49b-86ec43332559",
|
||||
"name": "AI Agent",
|
||||
"type": "@n8n/n8n-nodes-langchain.agent",
|
||||
"position": [
|
||||
2440,
|
||||
-20
|
||||
],
|
||||
"parameters": {
|
||||
"text": "={{ $json.Prompt }}",
|
||||
"options": {},
|
||||
"promptType": "define"
|
||||
},
|
||||
"typeVersion": 1.7
|
||||
},
|
||||
{
|
||||
"id": "f15b6af1-7af2-4515-be8f-960211118dce",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
60,
|
||||
-120
|
||||
],
|
||||
"parameters": {
|
||||
"width": 340,
|
||||
"height": 260,
|
||||
"content": "# Set The variables in your prompt here"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "163db6cc-5b06-4ae6-ac97-5890b37cdb18",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
520,
|
||||
-120
|
||||
],
|
||||
"parameters": {
|
||||
"color": 5,
|
||||
"content": "## The repo is currently public for you to test with"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "83ff6a86-a759-42a9-ace4-e20d57b906db",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1780,
|
||||
-200
|
||||
],
|
||||
"parameters": {
|
||||
"width": 360,
|
||||
"height": 260,
|
||||
"content": "## Replaces the values in the prompt with the variables in the \n# 'setVars' Node"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "7dd61153-84ac-4b59-b449-333825476c33",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
2000,
|
||||
180
|
||||
],
|
||||
"parameters": {
|
||||
"color": 3,
|
||||
"content": "## If you're missing variables they will be listed here"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "1f070dc3-3d25-41d8-b534-912ba7c8b2b0",
|
||||
"name": "Prompt Output",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
2800,
|
||||
-20
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "01a30683-c348-4712-a3b1-739fc4a17718",
|
||||
"name": "promptResponse",
|
||||
"type": "string",
|
||||
"value": "={{ $json.output }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "2d12a6e2-7976-41b0-8cb2-01466b28269d",
|
||||
"name": "Ollama Chat Model",
|
||||
"type": "@n8n/n8n-nodes-langchain.lmChatOllama",
|
||||
"position": [
|
||||
2480,
|
||||
200
|
||||
],
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"credentials": {
|
||||
"ollamaApi": {
|
||||
"id": "ERfZ8mAfQ1b0aoxZ",
|
||||
"name": "Ollama account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"active": false,
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "4327a337-59e7-4b5b-98e8-93c6be550972",
|
||||
"connections": {
|
||||
"If": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "replace variables",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"GitHub": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Extract from File",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"setVars": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "GitHub",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"AI Agent": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Prompt Output",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"SetPrompt": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check All Prompt Vars Present",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Extract from File": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "SetPrompt",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Ollama Chat Model": {
|
||||
"ai_languageModel": [
|
||||
[
|
||||
{
|
||||
"node": "AI Agent",
|
||||
"type": "ai_languageModel",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"replace variables": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set Completed Prompt",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set Completed Prompt": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "AI Agent",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check All Prompt Vars Present": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "If",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"When clicking \u2018Test workflow\u2019": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "setVars",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
2333
workflows/Stopanderror/1498_Stopanderror_Limit_Sync_Webhook.json
Normal file
2333
workflows/Stopanderror/1498_Stopanderror_Limit_Sync_Webhook.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,933 @@
|
||||
{
|
||||
"id": "IYgbtNpyB4E6Jbxo",
|
||||
"meta": {
|
||||
"instanceId": "35ae520798f87e479496aa54e1a1f89ffdf43eee77986511d08258a12b1edc98",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"name": "2. Refresh Pipedrive tokens",
|
||||
"tags": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "2b66edcd-c71a-4dac-971f-deb1b09ef85b",
|
||||
"name": "Stop and Error",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
1460,
|
||||
-80
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "Token refresh failed"
|
||||
},
|
||||
"typeVersion": 1,
|
||||
"alwaysOutputData": false
|
||||
},
|
||||
{
|
||||
"id": "b48d6760-766e-4b39-be35-89de7dc3ab5e",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
60,
|
||||
-300
|
||||
],
|
||||
"parameters": {
|
||||
"color": 5,
|
||||
"width": 872,
|
||||
"height": 97,
|
||||
"content": "## Step 2:\nCreate a workflow to refresh your access token when the access token requires a refresh."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "6119eef3-9ffa-45a1-b238-412738e7529e",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
280,
|
||||
-80
|
||||
],
|
||||
"parameters": {
|
||||
"height": 211,
|
||||
"content": "\n\n\n\n\n\n\n\nPost unique data to identify your row in Database and be able to fetch the existing access and refresh token"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "2d76be21-95e1-4747-b761-126b133e8264",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
980,
|
||||
-220
|
||||
],
|
||||
"parameters": {
|
||||
"content": "## Get token from pipedrive"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "9a44eb63-9d31-4b24-9171-1f9a828a5c52",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
100,
|
||||
-740
|
||||
],
|
||||
"parameters": {
|
||||
"color": 5,
|
||||
"width": 995,
|
||||
"height": 82,
|
||||
"content": "## Step 1:\nSave Refresh token and Access token to DB when authenticated by user and installed. "
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "f3247e6a-7c1c-4479-9f83-f3bc4146f254",
|
||||
"name": "Insert",
|
||||
"type": "n8n-nodes-base.supabase",
|
||||
"position": [
|
||||
1600,
|
||||
-660
|
||||
],
|
||||
"parameters": {
|
||||
"tableId": "App_tok",
|
||||
"fieldsUi": {
|
||||
"fieldValues": [
|
||||
{
|
||||
"fieldId": "ref_token",
|
||||
"fieldValue": "={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"refresh_token\"] }}"
|
||||
},
|
||||
{
|
||||
"fieldId": "acc_token",
|
||||
"fieldValue": "={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"access_token\"] }}"
|
||||
},
|
||||
{
|
||||
"fieldId": "Platform",
|
||||
"fieldValue": "Pipedrive"
|
||||
},
|
||||
{
|
||||
"fieldId": "created_at",
|
||||
"fieldValue": "={{$now.toUTC().toString()}}"
|
||||
},
|
||||
{
|
||||
"fieldId": "updated_at",
|
||||
"fieldValue": "={{$now.toUTC().toString()}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"supabaseApi": {
|
||||
"id": "tlmP1CXY3ExzjJDs",
|
||||
"name": "Supabase Automation"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "f7ad45d0-7055-45f4-9971-031ffebfdbda",
|
||||
"name": "Sticky Note4",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
500,
|
||||
-640
|
||||
],
|
||||
"parameters": {
|
||||
"content": "You can also use SET NODE + tobase64 function as done in step 2"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "e14e2dac-e84b-475f-a01b-14bb723eedc8",
|
||||
"name": "Sticky Note5",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
100,
|
||||
200
|
||||
],
|
||||
"parameters": {
|
||||
"color": 5,
|
||||
"width": 1644,
|
||||
"height": 80,
|
||||
"content": "## Step 3:\nMake an actual API call. In this example, we are using search person API. Please refer to Pipedrive API documentation for your specific use case. "
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "b450c928-e0e4-4f49-829e-03b61828d4d9",
|
||||
"name": "Get Pipedrive Token",
|
||||
"type": "n8n-nodes-base.supabase",
|
||||
"position": [
|
||||
600,
|
||||
660
|
||||
],
|
||||
"parameters": {
|
||||
"filters": {
|
||||
"conditions": [
|
||||
{
|
||||
"keyName": "Platform",
|
||||
"keyValue": "Pipedrive"
|
||||
},
|
||||
{
|
||||
"keyName": "AppId",
|
||||
"keyValue": "57db0bab2932f657"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tableId": "App_tok",
|
||||
"operation": "get"
|
||||
},
|
||||
"credentials": {
|
||||
"supabaseApi": {
|
||||
"id": "tlmP1CXY3ExzjJDs",
|
||||
"name": "Supabase Automation"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "f92a957a-d0ef-4037-8657-74e7fe74fe6d",
|
||||
"name": "Get contact from Pipedrive",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
900,
|
||||
660
|
||||
],
|
||||
"parameters": {
|
||||
"url": "=https://priyajain-sandbox.pipedrive.com/api/v2/persons/search?fields=email&term={{ $node[\"Receive request\"].json[\"body\"][\"person\"][\"email\"] }}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "=Bearer {{ $node[\"Get Pipedrive Token\"].json[\"acc_token\"] }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 4,
|
||||
"continueOnFail": true,
|
||||
"alwaysOutputData": false
|
||||
},
|
||||
{
|
||||
"id": "bff21156-3da0-4cf3-b3de-c24d8abe7577",
|
||||
"name": "Access Token Invalid",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
1160,
|
||||
700
|
||||
],
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json[\"error\"][\"message\"].includes(\"Invalid token: access token is invalid\") }}",
|
||||
"value2": "={{ true }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"combineOperation": "any"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "9fd832b1-2af9-48c2-9d57-86a9f34bdd78",
|
||||
"name": "Success",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"position": [
|
||||
1440,
|
||||
720
|
||||
],
|
||||
"parameters": {
|
||||
"options": {
|
||||
"responseCode": 200
|
||||
},
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ $node[\"Get contact from Pipedrive\"].json[\"body\"][\"data\"][\"items\"][\"0\"][\"item\"][\"name\"] }}"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "daf33b32-ff7b-4d7e-8fd0-d54dfaddf405",
|
||||
"name": "Refresh Access Token",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
1360,
|
||||
320
|
||||
],
|
||||
"parameters": {
|
||||
"url": "http://localhost:5678/webhook/937a8843-a28a-400a-b473-bdc598366fa0",
|
||||
"method": "POST",
|
||||
"options": {},
|
||||
"jsonBody": "{\n\n \"appId\":\"57db0bab2932f657\"\n\n}",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpBasicAuth"
|
||||
},
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
"id": "E2RYFiR9PotuglZv",
|
||||
"name": "PJ demo"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "6759a890-6c2a-4bb1-aae9-9b8723b9e143",
|
||||
"name": "Sticky Note6",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
580,
|
||||
420
|
||||
],
|
||||
"parameters": {
|
||||
"width": 668,
|
||||
"content": "## Loop back to fecth the refreshed Access Token\n### Note:\nYou can add further conditions and use Switch statemen tinstead of IF to validate API response based on your use case."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "d975ce9f-2ef2-46b1-9d30-4f6e06e19b7e",
|
||||
"name": "Sticky Note7",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
120,
|
||||
-960
|
||||
],
|
||||
"parameters": {
|
||||
"width": 1413,
|
||||
"content": "## 1. This workflow helps you create your own Oauth 2.0 token refresh system. It helps you have better control of your oauth 2.0 auth process.\n## 2. I am using Pipedrive API here. However, you can re-use this for other similar applications. "
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "40d59a94-563d-459c-91d0-4206c2a19704",
|
||||
"name": "Sticky Note8",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
180,
|
||||
580
|
||||
],
|
||||
"parameters": {
|
||||
"height": 248,
|
||||
"content": "A 3rd partyapplication posting the request to the webhook"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "03945766-570c-47db-82c6-2c973e45106d",
|
||||
"name": "convert clientId and secret to base64",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
560,
|
||||
-560
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nconst client_id = \"57db0bab2932f657\";\nconst client_secret = \"edfaba095e9e7ddefe2e960ce2e98345230a016d\";\n\n// Combine client_id and client_secret with a colon\nconst combinedString = client_id+\":\"+client_secret;\n\n// Encode the combined string in Base64\nconst encodedString = Buffer.from(combinedString).toString('base64');\n\n// Create the Authorization header value\nconst authorizationHeader = `Basic ${encodedString}`;\n\nreturn {\"authheader\":authorizationHeader};"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "8ca6eb93-6994-4536-b61e-d884c8515929",
|
||||
"name": "Generate Refresh Token from authcode",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"maxTries": 2,
|
||||
"position": [
|
||||
820,
|
||||
-560
|
||||
],
|
||||
"parameters": {
|
||||
"url": "https://oauth.pipedrive.com/oauth/token",
|
||||
"method": "POST",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"sendBody": true,
|
||||
"contentType": "form-urlencoded",
|
||||
"sendHeaders": true,
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "grant_type",
|
||||
"value": "authorization_code"
|
||||
},
|
||||
{
|
||||
"name": "code",
|
||||
"value": "={{$node[\"catch Auth code\"].json[\"query\"][\"code\"]}}"
|
||||
},
|
||||
{
|
||||
"name": "redirect_uri",
|
||||
"value": "={{ $node[\"catch Auth code\"].json[\"webhookUrl\"] }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "={{$node[\"convert clientId and secret to base64\"].json[\"authheader\"]}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"retryOnFail": false,
|
||||
"typeVersion": 4,
|
||||
"alwaysOutputData": false
|
||||
},
|
||||
{
|
||||
"id": "9c1b22e1-fd50-4c70-91cf-f4ea8cc7d3ac",
|
||||
"name": "Look for the related record in Supabase",
|
||||
"type": "n8n-nodes-base.supabase",
|
||||
"position": [
|
||||
1060,
|
||||
-540
|
||||
],
|
||||
"parameters": {
|
||||
"filters": {
|
||||
"conditions": [
|
||||
{
|
||||
"keyName": "Platform",
|
||||
"keyValue": "Pipedrive"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tableId": "App_tok",
|
||||
"operation": "get"
|
||||
},
|
||||
"credentials": {
|
||||
"supabaseApi": {
|
||||
"id": "tlmP1CXY3ExzjJDs",
|
||||
"name": "Supabase Automation"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1,
|
||||
"alwaysOutputData": true
|
||||
},
|
||||
{
|
||||
"id": "53602a58-d47a-4133-b9ec-4ea421a75eea",
|
||||
"name": "IF rec not found",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
1260,
|
||||
-540
|
||||
],
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"number": [
|
||||
{
|
||||
"value1": "={{ $json.values().length }}",
|
||||
"operation": "equal"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "38e5d91c-1bea-4f7a-8336-98748005d02e",
|
||||
"name": "Update tokns in the record",
|
||||
"type": "n8n-nodes-base.supabase",
|
||||
"position": [
|
||||
1600,
|
||||
-460
|
||||
],
|
||||
"parameters": {
|
||||
"filters": {
|
||||
"conditions": [
|
||||
{
|
||||
"keyName": "Platform",
|
||||
"keyValue": "Pipedrive",
|
||||
"condition": "eq"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tableId": "App_tok",
|
||||
"fieldsUi": {
|
||||
"fieldValues": [
|
||||
{
|
||||
"fieldId": "acc_token",
|
||||
"fieldValue": "={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"access_token\"] }}"
|
||||
},
|
||||
{
|
||||
"fieldId": "ref_token",
|
||||
"fieldValue": "={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"refresh_token\"] }}"
|
||||
},
|
||||
{
|
||||
"fieldId": "updated_at",
|
||||
"fieldValue": "={{$now.toUTC().toString()}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"matchType": "allFilters",
|
||||
"operation": "update"
|
||||
},
|
||||
"credentials": {
|
||||
"supabaseApi": {
|
||||
"id": "tlmP1CXY3ExzjJDs",
|
||||
"name": "Supabase Automation"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "43a2613d-7793-48c9-8934-57d9b713f5fe",
|
||||
"name": "Supabase- look for the record",
|
||||
"type": "n8n-nodes-base.supabase",
|
||||
"position": [
|
||||
600,
|
||||
-140
|
||||
],
|
||||
"parameters": {
|
||||
"filters": {
|
||||
"conditions": [
|
||||
{
|
||||
"keyName": "Platform",
|
||||
"keyValue": "Pipedrive"
|
||||
},
|
||||
{
|
||||
"keyName": "AppId",
|
||||
"keyValue": "={{ $node[\"Webhook\"].json[\"body\"][\"appId\"] }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tableId": "App_tok",
|
||||
"operation": "get"
|
||||
},
|
||||
"credentials": {
|
||||
"supabaseApi": {
|
||||
"id": "tlmP1CXY3ExzjJDs",
|
||||
"name": "Supabase Automation"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "366bd343-419c-4a77-b2ce-e6124a6cc291",
|
||||
"name": "combine client id and secret",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
840,
|
||||
-140
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "4330b857-6184-4ad8-82dc-a8b806ab8077",
|
||||
"name": "authheader",
|
||||
"type": "string",
|
||||
"value": "57db0bab2932f657:edfaba095e9e7ddefe2e960ce2e98345230a016d"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.3
|
||||
},
|
||||
{
|
||||
"id": "156acb8f-3a23-40ec-b011-9db8bfa6d98b",
|
||||
"name": "Get Pipedrive acess token",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
1060,
|
||||
-140
|
||||
],
|
||||
"parameters": {
|
||||
"url": "https://oauth.pipedrive.com/oauth/token",
|
||||
"method": "POST",
|
||||
"options": {},
|
||||
"sendBody": true,
|
||||
"contentType": "form-urlencoded",
|
||||
"sendHeaders": true,
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "grant_type",
|
||||
"value": "refresh_token"
|
||||
},
|
||||
{
|
||||
"name": "refresh_token",
|
||||
"value": "={{ $node[\"Supabase- look for the record\"].json[\"ref_token\"] }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "=Basic {{ $json[\"authheader\"].base64Encode() }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "3e20309e-6d50-444c-b9e1-cf6d6982e546",
|
||||
"name": "IF success",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
1240,
|
||||
-140
|
||||
],
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"string": [
|
||||
{
|
||||
"value1": "={{ Object.keys($input.first().json)[0]}}",
|
||||
"value2": "access_token"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "1e991aa7-9888-404d-8f80-bb6ce0a3b777",
|
||||
"name": "Update thr row with new access token",
|
||||
"type": "n8n-nodes-base.supabase",
|
||||
"position": [
|
||||
1420,
|
||||
-280
|
||||
],
|
||||
"parameters": {
|
||||
"filters": {
|
||||
"conditions": [
|
||||
{
|
||||
"keyName": "Platform",
|
||||
"keyValue": "Pipedrive",
|
||||
"condition": "eq"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tableId": "App_tok",
|
||||
"fieldsUi": {
|
||||
"fieldValues": [
|
||||
{
|
||||
"fieldId": "acc_token",
|
||||
"fieldValue": "={{ $node[\"Get Pipedrive acess token\"].json[\"access_token\"] }}"
|
||||
},
|
||||
{
|
||||
"fieldId": "ref_token",
|
||||
"fieldValue": "={{ $node[\"Get Pipedrive acess token\"].json[\"refresh_token\"] }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"matchType": "allFilters",
|
||||
"operation": "update"
|
||||
},
|
||||
"credentials": {
|
||||
"supabaseApi": {
|
||||
"id": "tlmP1CXY3ExzjJDs",
|
||||
"name": "Supabase Automation"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1,
|
||||
"alwaysOutputData": true
|
||||
},
|
||||
{
|
||||
"id": "d0989bad-9176-44a2-86ce-db07a5e8a34c",
|
||||
"name": "Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"position": [
|
||||
340,
|
||||
-140
|
||||
],
|
||||
"webhookId": "937a8843-a28a-400a-b473-bdc598366fa0",
|
||||
"parameters": {
|
||||
"path": "937a8843-a28a-400a-b473-bdc598366fa0",
|
||||
"options": {},
|
||||
"httpMethod": "POST",
|
||||
"responseMode": "lastNode",
|
||||
"authentication": "basicAuth"
|
||||
},
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
"id": "E2RYFiR9PotuglZv",
|
||||
"name": "PJ demo"
|
||||
}
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "108a2ea1-de2a-4df3-9d9f-0ce1b27a52e9",
|
||||
"name": "Receive request",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"position": [
|
||||
280,
|
||||
680
|
||||
],
|
||||
"webhookId": "47704458-bfa6-4d95-adf1-97fc78e35d8a",
|
||||
"parameters": {
|
||||
"path": "47704458-bfa6-4d95-adf1-97fc78e35d8a",
|
||||
"options": {},
|
||||
"httpMethod": "POST",
|
||||
"responseMode": "responseNode",
|
||||
"authentication": "basicAuth"
|
||||
},
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
"id": "E2RYFiR9PotuglZv",
|
||||
"name": "PJ demo"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "f983cfd1-52db-4839-88af-6386ec7c7256",
|
||||
"name": "catch Auth code",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"position": [
|
||||
300,
|
||||
-560
|
||||
],
|
||||
"webhookId": "aae545fb-a69d-4e20-91ce-65f105d0ea2f",
|
||||
"parameters": {
|
||||
"path": "aae545fb-a69d-4e20-91ce-65f105d0ea2f",
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"active": false,
|
||||
"pinData": {
|
||||
"Receive request": [
|
||||
{
|
||||
"json": {
|
||||
"body": {
|
||||
"person": {
|
||||
"email": "priya+solar@psw.com"
|
||||
}
|
||||
},
|
||||
"query": {},
|
||||
"params": {},
|
||||
"headers": {
|
||||
"host": "http://localhost:5678",
|
||||
"accept": "*/*",
|
||||
"user-agent": "PostmanRuntime/7.39.0",
|
||||
"content-type": "application/json",
|
||||
"authorization": "Basic xxxxxxx==",
|
||||
"cache-control": "no-cache",
|
||||
"postman-token": "41b79257-xxxx-xxxx-xxxx-9e004cae4e9e",
|
||||
"content-length": "52",
|
||||
"accept-encoding": "gzip, deflate, br",
|
||||
"x-forwarded-for": "54.86.50.139",
|
||||
"x-forwarded-host": "localhost:5678",
|
||||
"x-forwarded-proto": "https"
|
||||
},
|
||||
"webhookUrl": "http://localhost:5678/webhook-test/47704458-bfa6-4d95-adf1-97fc78e35d8a",
|
||||
"executionMode": "test"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"settings": {
|
||||
"callerPolicy": "workflowsFromSameOwner",
|
||||
"executionOrder": "v1",
|
||||
"saveManualExecutions": true
|
||||
},
|
||||
"versionId": "54499ed8-4677-400a-9e03-d0d84f8a97b5",
|
||||
"connections": {
|
||||
"Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Supabase- look for the record",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"IF success": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Update thr row with new access token",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Receive request": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get Pipedrive Token",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"catch Auth code": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "convert clientId and secret to base64",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"IF rec not found": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Insert",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Update tokns in the record",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get Pipedrive Token": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get contact from Pipedrive",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Access Token Invalid": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Refresh Access Token",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Success",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Refresh Access Token": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get Pipedrive Token",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get Pipedrive acess token": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "IF success",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get contact from Pipedrive": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Access Token Invalid",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"combine client id and secret": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get Pipedrive acess token",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Supabase- look for the record": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "combine client id and secret",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Generate Refresh Token from authcode": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Look for the related record in Supabase",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"convert clientId and secret to base64": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Generate Refresh Token from authcode",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Look for the related record in Supabase": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "IF rec not found",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,503 @@
|
||||
{
|
||||
"id": "QyMyf3zraY0wxXDf",
|
||||
"meta": {
|
||||
"instanceId": "ba3fa76a571c35110ef5f67e5099c9a5c1768ef125c2f3b804ba20de75248c0b",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"name": "Load Prompts from Github Repo and auto populate n8n expressions",
|
||||
"tags": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "34781446-b06e-41eb-83b8-b96bda1a5595",
|
||||
"name": "When clicking ‘Test workflow’",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"position": [
|
||||
-80,
|
||||
0
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c53b7243-7c82-47e0-a5ee-bd82bc51c386",
|
||||
"name": "GitHub",
|
||||
"type": "n8n-nodes-base.github",
|
||||
"position": [
|
||||
600,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"owner": {
|
||||
"__rl": true,
|
||||
"mode": "name",
|
||||
"value": "={{ $json.Account }}"
|
||||
},
|
||||
"filePath": "={{ $json.path }}{{ $json.prompt }}",
|
||||
"resource": "file",
|
||||
"operation": "get",
|
||||
"repository": {
|
||||
"__rl": true,
|
||||
"mode": "name",
|
||||
"value": "={{ $json.repo }}"
|
||||
},
|
||||
"additionalParameters": {}
|
||||
},
|
||||
"credentials": {
|
||||
"githubApi": {
|
||||
"id": "ostHZNoe8GSsbaQM",
|
||||
"name": "The GitHub account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "9976b199-b744-47a7-9d75-4b831274c01b",
|
||||
"name": "Extract from File",
|
||||
"type": "n8n-nodes-base.extractFromFile",
|
||||
"position": [
|
||||
840,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"operation": "text"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "26aa4e6a-c487-4cdf-91d5-df660cf826a6",
|
||||
"name": "setVars",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
180,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "150618c5-09b1-4f8b-a7b4-984662bf3381",
|
||||
"name": "Account",
|
||||
"type": "string",
|
||||
"value": "TPGLLC-US"
|
||||
},
|
||||
{
|
||||
"id": "22e8a3b0-bd53-485c-b971-7f1dd0686f0e",
|
||||
"name": "repo",
|
||||
"type": "string",
|
||||
"value": "PeresPrompts"
|
||||
},
|
||||
{
|
||||
"id": "ab94d0a1-ef3a-4fe9-9076-6882c6fda0ac",
|
||||
"name": "path",
|
||||
"type": "string",
|
||||
"value": "SEO/"
|
||||
},
|
||||
{
|
||||
"id": "66f122eb-1cbd-4769-aac8-3f05cdb6c116",
|
||||
"name": "prompt",
|
||||
"type": "string",
|
||||
"value": "keyword_research.md"
|
||||
},
|
||||
{
|
||||
"id": "03fe26a3-04e6-439c-abcb-d438fc5203c0",
|
||||
"name": "company",
|
||||
"type": "string",
|
||||
"value": "South Nassau Physical Therapy"
|
||||
},
|
||||
{
|
||||
"id": "c133d216-a457-4872-a060-0ba4d94549af",
|
||||
"name": "product",
|
||||
"type": "string",
|
||||
"value": "Manual Therapy"
|
||||
},
|
||||
{
|
||||
"id": "584864dd-2518-45e2-b501-02828757fc3a",
|
||||
"name": "features",
|
||||
"type": "string",
|
||||
"value": "pain relief"
|
||||
},
|
||||
{
|
||||
"id": "0c4594cc-302a-4215-bdad-12cf54f57967",
|
||||
"name": "sector",
|
||||
"type": "string",
|
||||
"value": "physical therapy"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "9d92f581-8cd9-448c-aa1d-023a96c1ddda",
|
||||
"name": "replace variables",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
1900,
|
||||
-20
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "// Fetch the prompt text\nconst prompt = $('SetPrompt').first().json.data; // Ensure the prompt contains placeholders like {{ some.node.value }}\n\n// Example variables object\nconst variables = {\n company: $('setVars').first().json.company,\n features: \"Awesome Software\",\n keyword: \"2025-02-07\"\n};\n\n// Function to replace placeholders dynamically\nconst replaceVariables = (text, vars) => {\n return text.replace(/{{(.*?)}}/g, (match, key) => {\n const trimmedKey = key.trim();\n \n // Extract last part after the last dot\n const finalKey = trimmedKey.split('.').pop();\n\n // Replace if key exists, otherwise leave placeholder unchanged\n return vars.hasOwnProperty(finalKey) ? vars[finalKey] : match;\n });\n};\n\n// Replace and return result\nreturn [{\n prompt: replaceVariables(prompt, variables)\n}];\n"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "6c6c4fde-6ee5-47a8-894d-44d1afcedc2a",
|
||||
"name": "If",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
1560,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "2717a7e5-095a-42bf-8b5b-8050c3389ec5",
|
||||
"operator": {
|
||||
"type": "boolean",
|
||||
"operation": "true",
|
||||
"singleValue": true
|
||||
},
|
||||
"leftValue": "={{ $json.success }}",
|
||||
"rightValue": "={{ $('Check All Prompt Vars Present').item.json.keys()}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "3b7712b8-5152-4f60-9401-03c89c39e227",
|
||||
"name": "Check All Prompt Vars Present",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
1280,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "// Get prompt text\nconst prompt = $json.data;\n\n// Extract variables inside {{ }} dynamically\nconst matches = [...prompt.matchAll(/{{(.*?)}}/g)];\nconst uniqueVars = [...new Set(matches.map(match => match[1].trim().split('.').pop()))];\n\n// Get variables from the Set Node\nconst setNodeVariables = $node[\"setVars\"].json || {};\n\n// Log extracted variables and Set Node keys\nconsole.log(\"Extracted Variables:\", uniqueVars);\nconsole.log(\"Set Node Keys:\", Object.keys(setNodeVariables));\n\n// Check if all required variables are present in the Set Node\nconst missingKeys = uniqueVars.filter(varName => !setNodeVariables.hasOwnProperty(varName));\n\nconsole.log(\"Missing Keys:\", missingKeys);\n\n// Return false if any required variable is missing, otherwise return true\nreturn [{\n success: missingKeys.length === 0,\n missingKeys: missingKeys\n}];\n"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "32618e10-3285-4c16-9e78-058dde329337",
|
||||
"name": "SetPrompt",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
1060,
|
||||
0
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "335b450d-542a-4714-83d8-ccc237188fc5",
|
||||
"name": "data",
|
||||
"type": "string",
|
||||
"value": "={{ $json.data }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "4d8b34ca-50dd-4f37-b4f7-542291461662",
|
||||
"name": "Stop and Error",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
1900,
|
||||
200
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "=Missing Prompt Variables : {{ $('Check All Prompt Vars Present').item.json.missingKeys }}\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "a78c1e17-9152-4241-bcdf-c0d723da543b",
|
||||
"name": "Set Completed Prompt",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
2220,
|
||||
-20
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "57a9625b-adea-4ee7-a72a-2be8db15f3d4",
|
||||
"name": "Prompt",
|
||||
"type": "string",
|
||||
"value": "={{ $json.prompt }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "51447c90-a222-4172-a49b-86ec43332559",
|
||||
"name": "AI Agent",
|
||||
"type": "@n8n/n8n-nodes-langchain.agent",
|
||||
"position": [
|
||||
2440,
|
||||
-20
|
||||
],
|
||||
"parameters": {
|
||||
"text": "={{ $json.Prompt }}",
|
||||
"options": {},
|
||||
"promptType": "define"
|
||||
},
|
||||
"typeVersion": 1.7
|
||||
},
|
||||
{
|
||||
"id": "f15b6af1-7af2-4515-be8f-960211118dce",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
60,
|
||||
-120
|
||||
],
|
||||
"parameters": {
|
||||
"width": 340,
|
||||
"height": 260,
|
||||
"content": "# Set The variables in your prompt here"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "163db6cc-5b06-4ae6-ac97-5890b37cdb18",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
520,
|
||||
-120
|
||||
],
|
||||
"parameters": {
|
||||
"color": 5,
|
||||
"content": "## The repo is currently public for you to test with"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "83ff6a86-a759-42a9-ace4-e20d57b906db",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1780,
|
||||
-200
|
||||
],
|
||||
"parameters": {
|
||||
"width": 360,
|
||||
"height": 260,
|
||||
"content": "## Replaces the values in the prompt with the variables in the \n# 'setVars' Node"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "7dd61153-84ac-4b59-b449-333825476c33",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
2000,
|
||||
180
|
||||
],
|
||||
"parameters": {
|
||||
"color": 3,
|
||||
"content": "## If you're missing variables they will be listed here"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "1f070dc3-3d25-41d8-b534-912ba7c8b2b0",
|
||||
"name": "Prompt Output",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
2800,
|
||||
-20
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "01a30683-c348-4712-a3b1-739fc4a17718",
|
||||
"name": "promptResponse",
|
||||
"type": "string",
|
||||
"value": "={{ $json.output }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "2d12a6e2-7976-41b0-8cb2-01466b28269d",
|
||||
"name": "Ollama Chat Model",
|
||||
"type": "@n8n/n8n-nodes-langchain.lmChatOllama",
|
||||
"position": [
|
||||
2480,
|
||||
200
|
||||
],
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"credentials": {
|
||||
"ollamaApi": {
|
||||
"id": "ERfZ8mAfQ1b0aoxZ",
|
||||
"name": "Ollama account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"active": false,
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "4327a337-59e7-4b5b-98e8-93c6be550972",
|
||||
"connections": {
|
||||
"If": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "replace variables",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"GitHub": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Extract from File",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"setVars": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "GitHub",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"AI Agent": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Prompt Output",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"SetPrompt": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check All Prompt Vars Present",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Extract from File": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "SetPrompt",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Ollama Chat Model": {
|
||||
"ai_languageModel": [
|
||||
[
|
||||
{
|
||||
"node": "AI Agent",
|
||||
"type": "ai_languageModel",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"replace variables": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set Completed Prompt",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set Completed Prompt": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "AI Agent",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check All Prompt Vars Present": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "If",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"When clicking ‘Test workflow’": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "setVars",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,576 @@
|
||||
{
|
||||
"id": "5Ycrm1MuK8htwd96",
|
||||
"meta": {
|
||||
"instanceId": "e5595d8cd58f3a24b5a8cf05dd852846c05423873db868a2b7d01a778210c45a",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"name": "Telegram RAG pdf",
|
||||
"tags": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "9fbce801-8c42-43a4-bc70-d93042d68b2c",
|
||||
"name": "Telegram Trigger",
|
||||
"type": "n8n-nodes-base.telegramTrigger",
|
||||
"position": [
|
||||
-220,
|
||||
240
|
||||
],
|
||||
"webhookId": "b178f034-9997-4832-9bb4-a43c3015506e",
|
||||
"parameters": {
|
||||
"updates": [
|
||||
"message"
|
||||
],
|
||||
"additionalFields": {}
|
||||
},
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.1
|
||||
},
|
||||
{
|
||||
"id": "1bfc1fbd-86b1-4a8a-9301-fe54497f5acd",
|
||||
"name": "Embeddings OpenAI",
|
||||
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
|
||||
"position": [
|
||||
720,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"credentials": {
|
||||
"openAiApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "d5ad7851-ed40-4b3a-b0d5-aeaf04362f1c",
|
||||
"name": "Default Data Loader",
|
||||
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
|
||||
"position": [
|
||||
860,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"dataType": "binary"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "fed803d0-49a2-4b82-8f20-a02a10caa027",
|
||||
"name": "Recursive Character Text Splitter",
|
||||
"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
|
||||
"position": [
|
||||
940,
|
||||
680
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"chunkSize": 3000,
|
||||
"chunkOverlap": 200
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "ab60f36f-fada-4812-8dbd-441ad372cb80",
|
||||
"name": "Stop and Error",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
220,
|
||||
840
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "An error occurred"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c87f1db3-7cc9-4063-9895-4b4d68ea53a1",
|
||||
"name": "Question and Answer Chain",
|
||||
"type": "@n8n/n8n-nodes-langchain.chainRetrievalQa",
|
||||
"position": [
|
||||
-280,
|
||||
500
|
||||
],
|
||||
"parameters": {
|
||||
"text": "={{ $json.message.text }}\nSearch the database with the retriever for information for the answer",
|
||||
"promptType": "define"
|
||||
},
|
||||
"typeVersion": 1.3
|
||||
},
|
||||
{
|
||||
"id": "c9bc4c80-8e57-48bc-a405-131ed7348c1d",
|
||||
"name": "Vector Store Retriever",
|
||||
"type": "@n8n/n8n-nodes-langchain.retrieverVectorStore",
|
||||
"position": [
|
||||
-240,
|
||||
680
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "0217056f-2b71-4308-adf1-19dcd4d2cc11",
|
||||
"name": "Pinecone Vector Store1",
|
||||
"type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
|
||||
"position": [
|
||||
-280,
|
||||
860
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"pineconeIndex": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": "telegram",
|
||||
"cachedResultName": "telegram"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"pineconeApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "693f9026-f47f-48dc-8e5d-e8b832a37235",
|
||||
"name": "Groq Chat Model",
|
||||
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
|
||||
"position": [
|
||||
-380,
|
||||
660
|
||||
],
|
||||
"parameters": {
|
||||
"model": "llama-3.1-70b-versatile",
|
||||
"options": {}
|
||||
},
|
||||
"credentials": {
|
||||
"groqApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "c7acf014-138f-4be7-b569-c309bb10e50d",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
500,
|
||||
73.04879287725316
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 1139.5159692915001,
|
||||
"height": 873.6068151028411,
|
||||
"content": "# Load data into database\nFetch file from **Telegram**, split it into chunks and insert into **Pinecone** index, a message from **Telegram** will be sent just to let the user know that the process finished"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "dd3b9d8b-5771-4a09-8c1b-794cb8737d5d",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-878.769,
|
||||
400
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 1344.7918019808176,
|
||||
"height": 806.8716167324012,
|
||||
"content": "# Chat with Database\n\n1. **Receive** the incoming chat message.\n2. **Retrieve** relevant chunks from the _vector store_.\n3. **Pass** these chunks to the model.\n\nThe model will use the retrieved information to **formulate a precise response**.\n"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "9aaf575a-5e40-407c-951c-10b1d16e5d3c",
|
||||
"name": "Check If is a document",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
220,
|
||||
240
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "8839993b-9fe7-4e1e-a1cc-fe5de6b0bb62",
|
||||
"operator": {
|
||||
"type": "object",
|
||||
"operation": "exists",
|
||||
"singleValue": true
|
||||
},
|
||||
"leftValue": "={{ $json.message.document }}",
|
||||
"rightValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "c1edb6bf-ba95-4a5f-9626-add673274086",
|
||||
"name": "Change to application/pdf",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
700,
|
||||
220
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "// Fun\u00e7\u00e3o para modificar os metadados do arquivo bin\u00e1rio\nfunction modifyBinaryMetadata(items) {\n for (const item of items) {\n if (item.binary && item.binary.data) {\n // Modifica o tipo MIME\n item.binary.data.mimeType = 'application/pdf';\n \n // Garante que o nome do arquivo termine com .pdf\n if (!item.binary.data.fileName.toLowerCase().endsWith('.pdf')) {\n item.binary.data.fileName += '.pdf';\n }\n \n // Atualiza o contentType no fileType (se existir)\n if (item.binary.data.fileType) {\n item.binary.data.fileType.contentType = 'application/pdf';\n }\n }\n }\n return items;\n}\n\n// Aplica a modifica\u00e7\u00e3o e retorna os itens atualizados\nreturn modifyBinaryMetadata($input.all());"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "ea4d4e74-8954-47f0-a3a0-662d47ea2298",
|
||||
"name": "Telegram get File",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"position": [
|
||||
520,
|
||||
220
|
||||
],
|
||||
"parameters": {
|
||||
"fileId": "={{ $json.message.document.file_id }}",
|
||||
"resource": "file"
|
||||
},
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "cf548bee-d5d5-4f1a-a059-932ea163e155",
|
||||
"name": "Embeddings",
|
||||
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
|
||||
"position": [
|
||||
-100,
|
||||
1080
|
||||
],
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"credentials": {
|
||||
"openAiApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "e3bd4759-80cc-42bb-ba53-f9e88e9ba916",
|
||||
"name": "Telegram Response",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"onError": "continueErrorOutput",
|
||||
"position": [
|
||||
160,
|
||||
560
|
||||
],
|
||||
"parameters": {
|
||||
"text": "={{ $json.response.text }}",
|
||||
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "e478df48-9e6d-4a84-89be-beb569914ae3",
|
||||
"name": "Telegram Response about Database",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"onError": "continueErrorOutput",
|
||||
"position": [
|
||||
1400,
|
||||
220
|
||||
],
|
||||
"parameters": {
|
||||
"text": "={{ $json.metadata.pdf.totalPages }} pages saved on Pinecone",
|
||||
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "5be7a321-1be6-4173-83de-3d569666718d",
|
||||
"name": "Stop and Error1",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
1400,
|
||||
580
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "An error occurred."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "aae26861-f34d-4b59-bd99-3662fbd6676c",
|
||||
"name": "Pinecone Vector Store",
|
||||
"type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
|
||||
"position": [
|
||||
880,
|
||||
220
|
||||
],
|
||||
"parameters": {
|
||||
"mode": "insert",
|
||||
"options": {},
|
||||
"pineconeIndex": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": "telegram",
|
||||
"cachedResultName": "telegram"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"pineconeApi": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "312fb807-4225-4630-ab32-aa12fe07c127",
|
||||
"name": "Limit to 1",
|
||||
"type": "n8n-nodes-base.limit",
|
||||
"position": [
|
||||
1220,
|
||||
220
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"active": true,
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"timezone": "America/Sao_Paulo",
|
||||
"callerPolicy": "workflowsFromSameOwner",
|
||||
"executionOrder": "v1",
|
||||
"saveManualExecutions": true
|
||||
},
|
||||
"versionId": "03612d23-6630-4ec6-8738-1dae593c8d23",
|
||||
"connections": {
|
||||
"Embeddings": {
|
||||
"ai_embedding": [
|
||||
[
|
||||
{
|
||||
"node": "Pinecone Vector Store1",
|
||||
"type": "ai_embedding",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Limit to 1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram Response about Database",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Groq Chat Model": {
|
||||
"ai_languageModel": [
|
||||
[
|
||||
{
|
||||
"node": "Question and Answer Chain",
|
||||
"type": "ai_languageModel",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Telegram Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check If is a document",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Embeddings OpenAI": {
|
||||
"ai_embedding": [
|
||||
[
|
||||
{
|
||||
"node": "Pinecone Vector Store",
|
||||
"type": "ai_embedding",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Telegram Response": {
|
||||
"main": [
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Telegram get File": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Change to application/pdf",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Default Data Loader": {
|
||||
"ai_document": [
|
||||
[
|
||||
{
|
||||
"node": "Pinecone Vector Store",
|
||||
"type": "ai_document",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Pinecone Vector Store": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Limit to 1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check If is a document": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram get File",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Question and Answer Chain",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Pinecone 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
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Change to application/pdf": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Pinecone Vector Store",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Question and Answer Chain": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram Response",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Telegram Response about Database": {
|
||||
"main": [
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Recursive Character Text Splitter": {
|
||||
"ai_textSplitter": [
|
||||
[
|
||||
{
|
||||
"node": "Default Data Loader",
|
||||
"type": "ai_textSplitter",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,540 @@
|
||||
{
|
||||
"id": "Y5URlIlbX4HDzWKA",
|
||||
"meta": {
|
||||
"instanceId": "6ae0aa8b6c9099f1f8ed1265281802eab47aaf5b2845f317791e4ac7ee5b7279",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"name": "airflow dag_run",
|
||||
"tags": [
|
||||
{
|
||||
"id": "YSelDQ3zfWB0LeVn",
|
||||
"name": "airflow",
|
||||
"createdAt": "2025-02-25T04:17:21.943Z",
|
||||
"updatedAt": "2025-02-25T04:17:21.943Z"
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "0d4457ef-7a88-4755-8bd2-b0e8148f86f4",
|
||||
"name": "Airflow: dag_run",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
380,
|
||||
-40
|
||||
],
|
||||
"parameters": {
|
||||
"url": "={{ $('airflow-api').item.json.prefix }}/api/v1/dags/{{ $('in data').item.json.dag_id }}/dagRuns",
|
||||
"method": "POST",
|
||||
"options": {},
|
||||
"jsonBody": "={\n \"conf\": {{ $('in data').item.json.conf }}\n}",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpBasicAuth"
|
||||
},
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
"id": "vTR4WWA7czRn2ULn",
|
||||
"name": "Airflow"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "acf477a0-aad5-402a-a5a0-543f3e277333",
|
||||
"name": "Airflow: dag_run - state",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
840,
|
||||
60
|
||||
],
|
||||
"parameters": {
|
||||
"url": "={{ $('airflow-api').item.json.prefix }}/api/v1/dags/{{ $('in data').item.json.dag_id }}/dagRuns/{{ $('Airflow: dag_run').item.json.dag_run_id }}",
|
||||
"options": {},
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpBasicAuth"
|
||||
},
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
"id": "vTR4WWA7czRn2ULn",
|
||||
"name": "Airflow"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "26982a6f-6281-4140-a05c-ea6f3f2c0cb2",
|
||||
"name": "count",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
1180,
|
||||
40
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "try {\n $('count').first().json.count += 1\n return {count:$('count').first().json.count};\n}\ncatch (error) {\n return {count:1};\n}"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "613718f6-ba7e-415c-8e07-0123224e1ac6",
|
||||
"name": "dag run fail",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
1180,
|
||||
400
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "dag run fail"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "66ba0e85-4608-418b-b27b-8cbc50f78319",
|
||||
"name": "if state == queued",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
520,
|
||||
60
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "0ae67986-09c0-443d-9262-075bfe94ca2e",
|
||||
"operator": {
|
||||
"name": "filter.operator.equals",
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
},
|
||||
"leftValue": "={{ $json.state }}",
|
||||
"rightValue": "queued"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "92176e9a-0ea7-48b0-9ca0-ea4ea8442cee",
|
||||
"name": "dag run wait too long",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
1500,
|
||||
40
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "dag run wait too long"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "6a05471f-232e-44d6-9dbb-583400537507",
|
||||
"name": "Airflow: dag_run - get result",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
1180,
|
||||
-140
|
||||
],
|
||||
"parameters": {
|
||||
"url": "={{ $('airflow-api').item.json.prefix }}/api/v1/dags/{{ $('in data').item.json.dag_id }}/dagRuns/{{ $('Airflow: dag_run').item.json.dag_run_id }}/taskInstances/{{ $('in data').item.json.task_id }}/xcomEntries/return_value",
|
||||
"options": {},
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpBasicAuth"
|
||||
},
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
"id": "vTR4WWA7czRn2ULn",
|
||||
"name": "Airflow"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "fb2211d5-cef2-4be2-b281-de315aa07093",
|
||||
"name": "Switch: state",
|
||||
"type": "n8n-nodes-base.switch",
|
||||
"position": [
|
||||
980,
|
||||
-40
|
||||
],
|
||||
"parameters": {
|
||||
"rules": {
|
||||
"values": [
|
||||
{
|
||||
"outputKey": "=success",
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "4d4ecf8a-c02b-4722-9528-1919cdf9b83e",
|
||||
"operator": {
|
||||
"name": "filter.operator.equals",
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
},
|
||||
"leftValue": "={{ $json.state }}",
|
||||
"rightValue": "success"
|
||||
}
|
||||
]
|
||||
},
|
||||
"renameOutput": true
|
||||
},
|
||||
{
|
||||
"outputKey": "queued",
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
},
|
||||
"leftValue": "={{ $json.state }}",
|
||||
"rightValue": "queued"
|
||||
}
|
||||
]
|
||||
},
|
||||
"renameOutput": true
|
||||
},
|
||||
{
|
||||
"outputKey": "running",
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "fa5d8524-334a-4ab1-b543-bba75cafd0ec",
|
||||
"operator": {
|
||||
"name": "filter.operator.equals",
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
},
|
||||
"leftValue": "={{ $json.state }}",
|
||||
"rightValue": "running"
|
||||
}
|
||||
]
|
||||
},
|
||||
"renameOutput": true
|
||||
},
|
||||
{
|
||||
"outputKey": "failed",
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "dd853677-c51c-4c06-8680-3c9d1829d6bd",
|
||||
"operator": {
|
||||
"name": "filter.operator.equals",
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
},
|
||||
"leftValue": "={{ $json.state }}",
|
||||
"rightValue": "failed"
|
||||
}
|
||||
]
|
||||
},
|
||||
"renameOutput": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"fallbackOutput": 3
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.2
|
||||
},
|
||||
{
|
||||
"id": "5941496a-a64d-432c-9103-e7bcae4b8d67",
|
||||
"name": "in data",
|
||||
"type": "n8n-nodes-base.executeWorkflowTrigger",
|
||||
"position": [
|
||||
100,
|
||||
-40
|
||||
],
|
||||
"parameters": {
|
||||
"workflowInputs": {
|
||||
"values": [
|
||||
{
|
||||
"name": "dag_id"
|
||||
},
|
||||
{
|
||||
"name": "task_id"
|
||||
},
|
||||
{
|
||||
"name": "conf"
|
||||
},
|
||||
{
|
||||
"name": "wait",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"name": "wait_time",
|
||||
"type": "number"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.1
|
||||
},
|
||||
{
|
||||
"id": "e77fed4a-b61a-4126-8be3-43ef8a832cfe",
|
||||
"name": "Wait",
|
||||
"type": "n8n-nodes-base.wait",
|
||||
"position": [
|
||||
700,
|
||||
-40
|
||||
],
|
||||
"webhookId": "3d164954-2926-4174-afc1-261dfdfa9e46",
|
||||
"parameters": {
|
||||
"amount": "={{ $('in data').item.json.hasOwnProperty('wait') ? $('in data').item.json.wait : 10 }}"
|
||||
},
|
||||
"typeVersion": 1.1
|
||||
},
|
||||
{
|
||||
"id": "8ffae842-4400-4667-85bb-50644ef10fc0",
|
||||
"name": "If count > wait_time",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
1320,
|
||||
140
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "1829d538-5633-4f5c-ad1b-285b084b35ee",
|
||||
"operator": {
|
||||
"type": "number",
|
||||
"operation": "gt"
|
||||
},
|
||||
"leftValue": "={{ $json.count }}",
|
||||
"rightValue": "={{ $('in data').item.json.hasOwnProperty('wait_time') ? $('in data').item.json.wait_time : 12 }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "c49d4a1b-6f25-471b-9c21-d3defb709dda",
|
||||
"name": "airflow-api",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
240,
|
||||
60
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "40a5ab5b-dee1-44c4-910a-d6b85af75aed",
|
||||
"name": "prefix",
|
||||
"type": "string",
|
||||
"value": "https://airflow.example.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
}
|
||||
],
|
||||
"active": false,
|
||||
"pinData": {
|
||||
"in data": [
|
||||
{
|
||||
"json": {
|
||||
"conf": "{\n \"image\": \"nginx\",\n \"tag\": \"latest\",\n \"tag_requested\": 1000\n}",
|
||||
"wait": 10,
|
||||
"dag_id": "image_tag_related",
|
||||
"task_id": "image_tag_related",
|
||||
"wait_time": 18
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "57fdbcfc-7950-4aff-9ac7-3c2a99a2c8c8",
|
||||
"connections": {
|
||||
"Wait": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Airflow: dag_run - state",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"count": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "If count > wait_time",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"in data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "airflow-api",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"airflow-api": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Airflow: dag_run",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Switch: state": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Airflow: dag_run - get result",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "count",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "count",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "dag run fail",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Airflow: dag_run": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "if state == queued",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"if state == queued": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Wait",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "dag run fail",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"If count > wait_time": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "dag run wait too long",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Wait",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Airflow: dag_run - state": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Switch: state",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Airflow: dag_run - get result": {
|
||||
"main": [
|
||||
[]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,765 @@
|
||||
{
|
||||
"id": "jhNsy4dPQYw9QDaa",
|
||||
"meta": {
|
||||
"instanceId": "1acdaec6c8e84424b4715cf41a9f7ec057947452db21cd2e22afbc454c8711cd",
|
||||
"templateId": "2683",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"name": "Zoom AI Meeting Assistant",
|
||||
"tags": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "9b4b21aa-c746-4b94-a4dd-12736a7d4098",
|
||||
"name": "OpenAI Chat Model",
|
||||
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
|
||||
"position": [
|
||||
2160,
|
||||
1040
|
||||
],
|
||||
"parameters": {
|
||||
"model": "gpt-4o",
|
||||
"options": {}
|
||||
},
|
||||
"credentials": {
|
||||
"openAiApi": {
|
||||
"id": "EjchNb5GBqYh0Cqn",
|
||||
"name": "OpenAi account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "536e360c-d668-4f58-8670-4e78ef579dbe",
|
||||
"name": "When clicking \u2018Test workflow\u2019",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"position": [
|
||||
160,
|
||||
460
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "eb2b6b98-ca3c-46a9-9d5f-9b5297441224",
|
||||
"name": "No Recording/Transcript available",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
880,
|
||||
660
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "={{ $json.error.cause.message }}"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "33ee5d8b-a373-44a8-9777-9386cf8cf008",
|
||||
"name": "Zoom: Get data of last meeting",
|
||||
"type": "n8n-nodes-base.zoom",
|
||||
"position": [
|
||||
340,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"filters": {
|
||||
"type": "scheduled"
|
||||
},
|
||||
"operation": "getAll",
|
||||
"returnAll": true,
|
||||
"authentication": "oAuth2"
|
||||
},
|
||||
"credentials": {
|
||||
"zoomOAuth2Api": {
|
||||
"id": "MmccxSST1g202tG2",
|
||||
"name": "Zoom account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "d67d1fcb-78d1-47e5-bc0e-5735f0f48350",
|
||||
"name": "Filter transcript URL",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"onError": "continueRegularOutput",
|
||||
"position": [
|
||||
880,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "ef149af8-7f9d-4e5a-8ccf-4a5f1e09eecc",
|
||||
"name": "transcript_file",
|
||||
"type": "string",
|
||||
"value": "={{ $json.recording_files.find(f => f.file_type === 'TRANSCRIPT').download_url }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "41665b4e-4d3e-4da9-9b0d-c6f9f0b2cde4",
|
||||
"name": "Filter: Only 1 item",
|
||||
"type": "n8n-nodes-base.splitInBatches",
|
||||
"position": [
|
||||
1060,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 3
|
||||
},
|
||||
{
|
||||
"id": "ea12b33a-ae01-403d-9f14-466dc8880874",
|
||||
"name": "Zoom: Get transcript file",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
1240,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"url": "={{ $json.transcript_file }}",
|
||||
"options": {},
|
||||
"authentication": "predefinedCredentialType",
|
||||
"nodeCredentialType": "zoomOAuth2Api"
|
||||
},
|
||||
"credentials": {
|
||||
"zoomOAuth2Api": {
|
||||
"id": "MmccxSST1g202tG2",
|
||||
"name": "Zoom account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "fb1c32c3-5161-499d-8cd6-7624fb78ed3e",
|
||||
"name": "Extract text from transcript file",
|
||||
"type": "n8n-nodes-base.extractFromFile",
|
||||
"position": [
|
||||
1420,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"operation": "text"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "87986fd3-37f0-48cd-942a-73fd3b5bd70f",
|
||||
"name": "Format transcript text",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
1600,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "70019192-02ef-4b0a-a747-3ca5f46aeeaa",
|
||||
"name": "transcript",
|
||||
"type": "string",
|
||||
"value": "={{ $json.data.split('\\r\\n\\r\\n').slice(1).map(block => {\n const lines = block.split('\\r\\n');\n return lines.slice(2).join(' ');\n}).join('\\n') }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "9af3559d-2fd0-481f-84d6-caefbcd8e4f2",
|
||||
"name": "Zoom: Get participants data",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
1760,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"url": "=https://api.zoom.us/v2/past_meetings/{{ $('Filter: Last 24 hours').item.json.id }}/participants",
|
||||
"options": {},
|
||||
"authentication": "predefinedCredentialType",
|
||||
"nodeCredentialType": "zoomOAuth2Api"
|
||||
},
|
||||
"credentials": {
|
||||
"zoomOAuth2Api": {
|
||||
"id": "MmccxSST1g202tG2",
|
||||
"name": "Zoom account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "03feecc5-e60d-45cb-bf29-6645afb86b4c",
|
||||
"name": "Create meeting summary",
|
||||
"type": "@n8n/n8n-nodes-langchain.openAi",
|
||||
"position": [
|
||||
1920,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"modelId": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": "gpt-4o",
|
||||
"cachedResultName": "GPT-4O"
|
||||
},
|
||||
"options": {},
|
||||
"messages": {
|
||||
"values": [
|
||||
{
|
||||
"content": "=Create a formal meeting minutes document from the following transcript and meeting details.\n\nMeeting Date: {{ $('Zoom: Get data of last meeting').item.json.start_time }} // This needs to be formatted from the meeting details\nParticipants: {{ $json.participants.map(p => p.name + ' (' + p.user_email + ')').join(', ') }}\n\nTranscript:\n{{ $('Format transcript text').item.json.transcript }}\n\nPlease create the minutes in the following format:\n\nMeeting on [Date]\n\nParticipants:\n[List of participants with email addresses]\n\nSummary of the Meeting:\n[Brief and concise summary of the topics discussed]\n\nTasks:\n- [Task] (Responsible: [Name])\n- ...\n\nImportant Dates:\n- [Date] ([Context])\n- ...\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"openAiApi": {
|
||||
"id": "EjchNb5GBqYh0Cqn",
|
||||
"name": "OpenAi account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.8
|
||||
},
|
||||
{
|
||||
"id": "5edc73f7-aa1b-47ae-97f7-c6f897e914a6",
|
||||
"name": "Sort for mail delivery",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
2240,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "cc51b7e4-d5c2-4cd4-9488-4d181eaaa02e",
|
||||
"name": "subject",
|
||||
"type": "string",
|
||||
"value": "=Meeting summary: {{ $('Zoom: Get data of last meeting').item.json.topic }} on {{ $('Zoom: Get data of last meeting').item.json.start_time }}"
|
||||
},
|
||||
{
|
||||
"id": "f3940ea2-9084-4c25-828e-5ddaa428ec83",
|
||||
"name": "=to",
|
||||
"type": "string",
|
||||
"value": "={{ $('Zoom: Get participants data').item.json.participants[0].user_email }}"
|
||||
},
|
||||
{
|
||||
"id": "1211af5b-2240-44ce-9df7-63d93f57806e",
|
||||
"name": "body",
|
||||
"type": "string",
|
||||
"value": "={{ $json.message.content }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "29ad24ba-016b-4e65-b8c8-908d8e2207c5",
|
||||
"name": "Format to html",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
2400,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "const items = [];\n\nfor (const item of $input.all()) {\n const body = item.json.body;\n if (!body) continue;\n\n // Simple split approach\n const sections = body.split('\\n\\n');\n const title = sections[0].replace(/\\*\\*/g, '');\n const participants = sections[1].split('\\n').slice(1).join('\\n');\n const summary = sections[2].split('\\n').slice(1).join('\\n');\n const tasks = sections[3].split('\\n').slice(1).join('\\n');\n const dates = sections[4].split('\\n').slice(1).join('\\n');\n\n const html = `<html>\n<body style=\"font-family: Arial, sans-serif; max-width: 800px; margin: 20px;\">\n<h1 style=\"color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px;\">${title}</h1>\n<h2 style=\"color: #2c3e50; margin-top: 20px;\">Participants:</h2>\n<ul style=\"list-style-type: none; padding-left: 20px;\">\n${participants.split('\\n').map(p => `<li>${p.replace('- ', '')}</li>`).join('\\n')}\n</ul>\n<h2 style=\"color: #2c3e50; margin-top: 20px;\">Meeting Summary:</h2>\n<p style=\"margin-left: 20px;\">${summary}</p>\n<h2 style=\"color: #2c3e50; margin-top: 20px;\">Tasks:</h2>\n<ul style=\"margin-left: 20px;\">\n${tasks.split('\\n').map(t => `<li>${t.replace('- ', '')}</li>`).join('\\n')}\n</ul>\n<h2 style=\"color: #2c3e50; margin-top: 20px;\">Important Dates:</h2>\n<ul style=\"margin-left: 20px;\">\n${dates.split('\\n').map(d => `<li>${d.replace('- ', '')}</li>`).join('\\n')}\n</ul>\n</body>\n</html>`;\n\n items.push({\n json: {\n html,\n to: item.json.to,\n subject: item.json.subject\n }\n });\n}\n\nreturn items;"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "60c9d778-d97a-4e17-858c-804f523590e5",
|
||||
"name": "Send meeting summary",
|
||||
"type": "n8n-nodes-base.emailSend",
|
||||
"position": [
|
||||
2560,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"html": "={{ $json.html }}",
|
||||
"options": {},
|
||||
"subject": "={{ $json.subject }}",
|
||||
"toEmail": "={{ $json.to }}",
|
||||
"fromEmail": "friedemann.schuetz@posteo.de"
|
||||
},
|
||||
"credentials": {
|
||||
"smtp": {
|
||||
"id": "OFGEnOq5l8U8Lb3U",
|
||||
"name": "SMTP account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.1
|
||||
},
|
||||
{
|
||||
"id": "39d8bb49-d9e9-46e3-89b3-fcbf9345bad8",
|
||||
"name": "Create tasks",
|
||||
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
|
||||
"position": [
|
||||
2340,
|
||||
1040
|
||||
],
|
||||
"parameters": {
|
||||
"name": "create_task",
|
||||
"schemaType": "manual",
|
||||
"workflowId": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": "zSKQLEObdU9RiThI",
|
||||
"cachedResultName": "create_task"
|
||||
},
|
||||
"description": "=Use this tool to create a task. \nFor task creation use only action items for me Friedemann, don't use action items for other participants.",
|
||||
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"items\": {\n \"type\": \"array\",\n \"description\": \"An array of tasks\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"description\": \"The name of the task\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"A detailed description of the task\"\n },\n \"due_date\": {\n \"type\": \"string\",\n \"description\": \"Due Date\"\n },\n \"priority\": {\n \"type\": \"string\",\n \"description\": \"Priority. . Please capitalize first letter\"\n },\n \"project_name\": {\n \"type\": \"string\",\n \"description\": \"Name of the project. Word 'Project' shouldn't be included\"\n }\n },\n \"required\": [\n \"name\",\n \"description\",\n \"due_date\",\n \"priority\"\n ],\n \"additionalProperties\": false\n }\n }\n },\n \"required\": [\n \"items\"\n ],\n \"additionalProperties\": false\n}",
|
||||
"specifyInputSchema": true
|
||||
},
|
||||
"typeVersion": 1.3
|
||||
},
|
||||
{
|
||||
"id": "9fa8eb9e-d4fc-4a2a-9843-2f51055944e9",
|
||||
"name": "Create tasks and follow-up call",
|
||||
"type": "@n8n/n8n-nodes-langchain.agent",
|
||||
"position": [
|
||||
2240,
|
||||
720
|
||||
],
|
||||
"parameters": {
|
||||
"text": "=<system_prompt>\n\nTODAY IS: {{ $now }}\n\nYOU ARE A MEETING ASSISTANT FOR AUTOMATION IN N8N. YOUR TASK IS TO EFFICIENTLY AND PRECISELY PROCESS INFORMATION FROM ZOOM MEETINGS TO GENERATE TO-DOS AND SCHEDULE FOLLOW-UP MEETINGS. YOU HAVE ACCESS TO THE FOLLOWING DATA:\n\n### INPUTS ###\n- **MEETING TITLE**: {{ $('Zoom: Get data of last meeting').item.json.topic }}\n- **PARTICIPANTS**: {{ $('Zoom: Get participants data').item.json.participants[0].name }}\n- **TRANSCRIPT**: {{ $('Format transcript text').item.json.transcript }}\n\n### YOUR TASKS ###\n1. **CREATE TO-DOS**:\n - IDENTIFY TASKS AND TO-DOS IN THE TRANSCRIPT.\n - FORMULATE CLEAR, CONCRETE TASKS.\n - PASS THESE TASKS TO THE TOOL \"Create tasks\" TO SAVE THEM IN CLICKUP. \n - DATA STRUCTURE:\n - **TASK DESCRIPTION**: Brief description of the task.\n - **ASSIGNED PERSON**: First name from the participant list.\n - **DUE DATE**: Use any date mentioned in the transcript; otherwise, set to \"Not specified.\"\n\n2. **CREATE MEETING**:\n - ANALYZE THE TRANSCRIPT TO IDENTIFY INFORMATION ABOUT THE NEXT MEETING (DATE, TIME, AND TOPIC).\n - PASS THIS INFORMATION TO THE TOOL \"Create follow-up call.\"\n - DATA STRUCTURE:\n - **MEETING TITLE**: \"Follow-up: [Meeting Title]\"\n - **DATE AND TIME**: Determined from the transcript or set to \"Next Tuesday at 10:00 AM\" if no information is provided.\n - **PARTICIPANTS**: Add all participants from the list.\n\n### CHAIN OF THOUGHTS ###\n1. **UNDERSTAND**: Read and analyze the provided inputs (title, participants, transcript).\n2. **IDENTIFY**: Extract relevant information for the to-dos and the next meeting.\n3. **DIVIDE**: Split the task into two separate processes: creating to-dos and creating the meeting.\n4. **STRUCTURE**: Format the results in the required structure for the respective tools.\n5. **TRANSMIT**: Pass the data to the designated tools in n8n.\n6. **VERIFY**: Ensure the data is correct and complete.\n\n### WHAT YOU SHOULD NOT DO ###\n- **NEVER**: Create unclear or vague to-dos.\n- **NEVER**: Ignore missing data \u2013 use default values where uncertain.\n- **NEVER**: Overlook information from the inputs or make incorrect connections.\n- **NEVER**: Transmit tasks or meetings without proper formatting.\n\n### OUTPUT EXAMPLES ###\n1. **TO-DO**:\n - **TASK DESCRIPTION**: \"Prepare presentation for the next meeting.\"\n - **ASSIGNED PERSON**: \"John Doe.\"\n - **DUE DATE**: \"2025-01-25.\"\n\n2. **MEETING**:\n - **MEETING TITLE**: \"Follow-up: Project Discussion.\"\n - **DATE AND TIME**: \"2025-01-28 at 10:00 AM.\"\n - **PARTICIPANTS**: \"John Doe, Jane Example.\"\n\n### NOTES ###\n- EXECUTE YOUR TASKS WITH THE HIGHEST PRECISION AND CONTEXT SENSITIVITY.\n- RELY ON THE PROVIDED DATA AND DEFAULT VALUES WHERE NECESSARY.\n</system_prompt>\n",
|
||||
"agent": "openAiFunctionsAgent",
|
||||
"options": {},
|
||||
"promptType": "define"
|
||||
},
|
||||
"typeVersion": 1.7
|
||||
},
|
||||
{
|
||||
"id": "05515784-c99d-4197-9d88-62350bacfb7b",
|
||||
"name": "Create follow-up call",
|
||||
"type": "n8n-nodes-base.microsoftOutlookTool",
|
||||
"position": [
|
||||
2500,
|
||||
1040
|
||||
],
|
||||
"parameters": {
|
||||
"subject": "={{ $fromAI(\"meeting_name\",\"Meeting name\",\"string\") }}",
|
||||
"resource": "event",
|
||||
"operation": "create",
|
||||
"calendarId": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": "AQMkADAwATNiZmYAZC1jYjE5LWExMzQtMDACLTAwCgBGAAAD1gD8iHcpKEiYQc0w4fCLUgcA-79r8r8ac0aInYGVxRUqCwAAAgEGAAAA-79r8r8ac0aInYGVxRUqCwAAAkH-AAAA",
|
||||
"cachedResultName": "Calendar"
|
||||
},
|
||||
"endDateTime": "={{ $fromAI(\"end_date_time\",\"Date and time of meeting end\",\"string\") }}",
|
||||
"startDateTime": "={{ $fromAI(\"start_date_time\",\"Date and time of meeting start\",\"string\") }}",
|
||||
"descriptionType": "manual",
|
||||
"toolDescription": "=Use tool to create Outlook Calendar Event. Use this tool only when transcript contains information that call should be scheduled.",
|
||||
"additionalFields": {
|
||||
"timeZone": "Europe/Berlin"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"microsoftOutlookOAuth2Api": {
|
||||
"id": "DNMkqql32uwVETij",
|
||||
"name": "Microsoft Outlook account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "2f00c2c6-2389-429c-8c9a-f8f1fbfb6524",
|
||||
"name": "Filter: Last 24 hours",
|
||||
"type": "n8n-nodes-base.filter",
|
||||
"position": [
|
||||
500,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "de097a4f-1f3e-4dc0-9ab6-139311ff4676",
|
||||
"operator": {
|
||||
"type": "dateTime",
|
||||
"operation": "afterOrEquals"
|
||||
},
|
||||
"leftValue": "={{ $json.start_time }}",
|
||||
"rightValue": "={{$now.minus({ hours: 24 }).toISO()}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "fd353a51-eac3-4d04-ae06-dd8e90b82990",
|
||||
"name": "Execute Workflow Trigger",
|
||||
"type": "n8n-nodes-base.executeWorkflowTrigger",
|
||||
"disabled": true,
|
||||
"position": [
|
||||
1280,
|
||||
980
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "40480f97-699b-4a49-867a-54950702af79",
|
||||
"name": "Split Out",
|
||||
"type": "n8n-nodes-base.splitOut",
|
||||
"position": [
|
||||
1500,
|
||||
980
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"fieldToSplitOut": "query.items"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "22e6165f-d7c2-4b23-be63-00c76505cdd3",
|
||||
"name": "ClickUp",
|
||||
"type": "n8n-nodes-base.clickUp",
|
||||
"position": [
|
||||
1720,
|
||||
980
|
||||
],
|
||||
"parameters": {
|
||||
"list": "901207046581",
|
||||
"name": "={{ $json.name }}",
|
||||
"team": "9012366821",
|
||||
"space": "90122025710",
|
||||
"folder": "90123813376",
|
||||
"authentication": "oAuth2",
|
||||
"additionalFields": {
|
||||
"content": "={{ $json.description }}",
|
||||
"dueDate": "={{ $json.due_date }}"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"clickUpOAuth2Api": {
|
||||
"id": "KYxmoCCdfSkwWlXE",
|
||||
"name": "ClickUp account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "742a411e-05cb-4aa0-a541-7b67e613e2bb",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1060,
|
||||
900
|
||||
],
|
||||
"parameters": {
|
||||
"width": 1000,
|
||||
"height": 280,
|
||||
"content": "## Sub workflow: Create Task in ClickUp"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "ebc5f1df-b417-4977-9700-b71b49a15cbb",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
140,
|
||||
660
|
||||
],
|
||||
"parameters": {
|
||||
"width": 660,
|
||||
"height": 520,
|
||||
"content": "## Welcome to my Zoom AI Meeting Assistant Workflow!\n\n### This workflow has the following sequence:\n\n1. manual trigger (Can be replaced by a scheduled trigger or a webhook)\n2. retrieval of of Zoom meeting data\n3. filter the events of the last 24 hours\n4. retrieval of transcripts and extract of the text\n5. creating a meeting summary, format to html and send per mail\n6. create tasks and follow-up call (if discussed in the meeting) in ClickUp/Outlook (can be replaced by Gmail, Airtable, and so forth) via sub workflow\n\n### The following accesses are required for the workflow:\n- Zoom Workspace (via API and HTTP Request): [Documentation](https://docs.n8n.io/integrations/builtin/credentials/zoom/)\n- Microsoft Outlook: [Documentation](https://docs.n8n.io/integrations/builtin/credentials/microsoft/)\n- ClickUp: [Documentation](https://docs.n8n.io/integrations/builtin/credentials/clickup/)\n- AI API access (e.g. via OpenAI, Anthropic, Google or Ollama)\n- SMTP access data (for sending the mail)\n\nYou can contact me via LinkedIn, if you have any questions: https://www.linkedin.com/in/friedemann-schuetz"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "d9109d09-eb1f-4685-a78b-d17e3dd22438",
|
||||
"name": "Zoom: Get transcripts data",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"onError": "continueErrorOutput",
|
||||
"position": [
|
||||
680,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"url": "=https://api.zoom.us/v2/meetings/{{ $json.id }}/recordings",
|
||||
"options": {},
|
||||
"authentication": "predefinedCredentialType",
|
||||
"nodeCredentialType": "zoomOAuth2Api"
|
||||
},
|
||||
"credentials": {
|
||||
"zoomOAuth2Api": {
|
||||
"id": "MmccxSST1g202tG2",
|
||||
"name": "Zoom account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
}
|
||||
],
|
||||
"active": false,
|
||||
"pinData": {
|
||||
"Execute Workflow Trigger": [
|
||||
{
|
||||
"json": {
|
||||
"query": {
|
||||
"items": [
|
||||
{
|
||||
"name": "Partner abtelefonieren",
|
||||
"due_date": "2025-01-06",
|
||||
"priority": "High",
|
||||
"description": "Am 6. Januar alle Partner anrufen, um zu kl\u00e4ren, ob Interesse an einer weiteren Kooperation besteht und wie diese dargestellt werden kann.",
|
||||
"project_name": "Partnerkooperationen"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"settings": {},
|
||||
"versionId": "7dd6e3c4-87d1-4d88-ab7c-10e041e64674",
|
||||
"connections": {
|
||||
"Split Out": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "ClickUp",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Create tasks": {
|
||||
"ai_tool": [
|
||||
[
|
||||
{
|
||||
"node": "Create tasks and follow-up call",
|
||||
"type": "ai_tool",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format to html": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send meeting summary",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"OpenAI Chat Model": {
|
||||
"ai_languageModel": [
|
||||
[
|
||||
{
|
||||
"node": "Create tasks and follow-up call",
|
||||
"type": "ai_languageModel",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Filter: Only 1 item": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Filter: Only 1 item",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Zoom: Get transcript file",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Send meeting summary": {
|
||||
"main": [
|
||||
[]
|
||||
]
|
||||
},
|
||||
"Create follow-up call": {
|
||||
"ai_tool": [
|
||||
[
|
||||
{
|
||||
"node": "Create tasks and follow-up call",
|
||||
"type": "ai_tool",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Filter transcript URL": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Filter: Only 1 item",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Filter: Last 24 hours": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Zoom: Get transcripts data",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Create meeting summary": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Sort for mail delivery",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Create tasks and follow-up call",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format transcript text": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Zoom: Get participants data",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Sort for mail delivery": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Format to html",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Workflow Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Split Out",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Zoom: Get transcript file": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Extract text from transcript file",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Zoom: Get transcripts data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Filter transcript URL",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "No Recording/Transcript available",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Zoom: Get participants data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Create meeting summary",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Zoom: Get data of last meeting": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Filter: Last 24 hours",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Create tasks and follow-up call": {
|
||||
"main": [
|
||||
[]
|
||||
]
|
||||
},
|
||||
"Extract text from transcript file": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Format transcript text",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"When clicking \u2018Test workflow\u2019": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Zoom: Get data of last meeting",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
1849
workflows/Stopanderror/1823_Stopanderror_Wait_Create_Webhook.json
Normal file
1849
workflows/Stopanderror/1823_Stopanderror_Wait_Create_Webhook.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,795 @@
|
||||
{
|
||||
"id": "jhNsy4dPQYw9QDaa",
|
||||
"meta": {
|
||||
"instanceId": "1acdaec6c8e84424b4715cf41a9f7ec057947452db21cd2e22afbc454c8711cd",
|
||||
"templateId": "2683",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"name": "Zoom AI Meeting Assistant",
|
||||
"tags": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "536e360c-d668-4f58-8670-4e78ef579dbe",
|
||||
"name": "When clicking ‘Test workflow’",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"position": [
|
||||
160,
|
||||
460
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "eb2b6b98-ca3c-46a9-9d5f-9b5297441224",
|
||||
"name": "No Recording/Transcript available",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
880,
|
||||
660
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "={{ $json.error.cause.message }}"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "33ee5d8b-a373-44a8-9777-9386cf8cf008",
|
||||
"name": "Zoom: Get data of last meeting",
|
||||
"type": "n8n-nodes-base.zoom",
|
||||
"position": [
|
||||
340,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"filters": {
|
||||
"type": "scheduled"
|
||||
},
|
||||
"operation": "getAll",
|
||||
"returnAll": true,
|
||||
"authentication": "oAuth2"
|
||||
},
|
||||
"credentials": {
|
||||
"zoomOAuth2Api": {
|
||||
"id": "MmccxSST1g202tG2",
|
||||
"name": "Zoom account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "d67d1fcb-78d1-47e5-bc0e-5735f0f48350",
|
||||
"name": "Filter transcript URL",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"onError": "continueRegularOutput",
|
||||
"position": [
|
||||
880,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "ef149af8-7f9d-4e5a-8ccf-4a5f1e09eecc",
|
||||
"name": "transcript_file",
|
||||
"type": "string",
|
||||
"value": "={{ $json.recording_files.find(f => f.file_type === 'TRANSCRIPT').download_url }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "41665b4e-4d3e-4da9-9b0d-c6f9f0b2cde4",
|
||||
"name": "Filter: Only 1 item",
|
||||
"type": "n8n-nodes-base.splitInBatches",
|
||||
"position": [
|
||||
1060,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"typeVersion": 3
|
||||
},
|
||||
{
|
||||
"id": "ea12b33a-ae01-403d-9f14-466dc8880874",
|
||||
"name": "Zoom: Get transcript file",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
1240,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"url": "={{ $json.transcript_file }}",
|
||||
"options": {},
|
||||
"authentication": "predefinedCredentialType",
|
||||
"nodeCredentialType": "zoomOAuth2Api"
|
||||
},
|
||||
"credentials": {
|
||||
"zoomOAuth2Api": {
|
||||
"id": "MmccxSST1g202tG2",
|
||||
"name": "Zoom account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "fb1c32c3-5161-499d-8cd6-7624fb78ed3e",
|
||||
"name": "Extract text from transcript file",
|
||||
"type": "n8n-nodes-base.extractFromFile",
|
||||
"position": [
|
||||
1420,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"operation": "text"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "87986fd3-37f0-48cd-942a-73fd3b5bd70f",
|
||||
"name": "Format transcript text",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
1600,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "70019192-02ef-4b0a-a747-3ca5f46aeeaa",
|
||||
"name": "transcript",
|
||||
"type": "string",
|
||||
"value": "={{ $json.data.split('\\r\\n\\r\\n').slice(1).map(block => {\n const lines = block.split('\\r\\n');\n return lines.slice(2).join(' ');\n}).join('\\n') }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "9af3559d-2fd0-481f-84d6-caefbcd8e4f2",
|
||||
"name": "Zoom: Get participants data",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
1760,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"url": "=https://api.zoom.us/v2/past_meetings/{{ $('Filter: Last 24 hours').item.json.id }}/participants",
|
||||
"options": {},
|
||||
"authentication": "predefinedCredentialType",
|
||||
"nodeCredentialType": "zoomOAuth2Api"
|
||||
},
|
||||
"credentials": {
|
||||
"zoomOAuth2Api": {
|
||||
"id": "MmccxSST1g202tG2",
|
||||
"name": "Zoom account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "5edc73f7-aa1b-47ae-97f7-c6f897e914a6",
|
||||
"name": "Sort for mail delivery",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
2240,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "cc51b7e4-d5c2-4cd4-9488-4d181eaaa02e",
|
||||
"name": "subject",
|
||||
"type": "string",
|
||||
"value": "=Meeting summary: {{ $('Zoom: Get data of last meeting').item.json.topic }} on {{ DateTime.fromISO($('Zoom: Get data of last meeting').item.json.start_time).toFormat('yyyy-MM-dd HH:mm') }}"
|
||||
},
|
||||
{
|
||||
"id": "f3940ea2-9084-4c25-828e-5ddaa428ec83",
|
||||
"name": "=to",
|
||||
"type": "string",
|
||||
"value": "={{ $('Zoom: Get participants data').item.json.participants[0].user_email }}"
|
||||
},
|
||||
{
|
||||
"id": "1211af5b-2240-44ce-9df7-63d93f57806e",
|
||||
"name": "body",
|
||||
"type": "string",
|
||||
"value": "={{ $json.output }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "29ad24ba-016b-4e65-b8c8-908d8e2207c5",
|
||||
"name": "Format to html",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"position": [
|
||||
2400,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"jsCode": "const items = [];\n\nfor (const item of $input.all()) {\n const body = item.json.body;\n if (!body) continue;\n\n // Simple split approach\n const sections = body.split('\\n\\n');\n const title = sections[0].replace(/\\*\\*/g, '');\n const participants = sections[1].split('\\n').slice(1).join('\\n');\n const summary = sections[2].split('\\n').slice(1).join('\\n');\n const tasks = sections[3].split('\\n').slice(1).join('\\n');\n const dates = sections[4].split('\\n').slice(1).join('\\n');\n\n const html = `<html>\n<body style=\"font-family: Arial, sans-serif; max-width: 800px; margin: 20px;\">\n<h1 style=\"color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px;\">${title}</h1>\n<h2 style=\"color: #2c3e50; margin-top: 20px;\">Participants:</h2>\n<ul style=\"list-style-type: none; padding-left: 20px;\">\n${participants.split('\\n').map(p => `<li>${p.replace('- ', '')}</li>`).join('\\n')}\n</ul>\n<h2 style=\"color: #2c3e50; margin-top: 20px;\">Meeting Summary:</h2>\n<p style=\"margin-left: 20px;\">${summary}</p>\n<h2 style=\"color: #2c3e50; margin-top: 20px;\">Tasks:</h2>\n<ul style=\"margin-left: 20px;\">\n${tasks.split('\\n').map(t => `<li>${t.replace('- ', '')}</li>`).join('\\n')}\n</ul>\n<h2 style=\"color: #2c3e50; margin-top: 20px;\">Important Dates:</h2>\n<ul style=\"margin-left: 20px;\">\n${dates.split('\\n').map(d => `<li>${d.replace('- ', '')}</li>`).join('\\n')}\n</ul>\n</body>\n</html>`;\n\n items.push({\n json: {\n html,\n to: item.json.to,\n subject: item.json.subject\n }\n });\n}\n\nreturn items;"
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "60c9d778-d97a-4e17-858c-804f523590e5",
|
||||
"name": "Send meeting summary",
|
||||
"type": "n8n-nodes-base.emailSend",
|
||||
"position": [
|
||||
2560,
|
||||
460
|
||||
],
|
||||
"webhookId": "81c4f081-f3d1-44c3-a344-3f735f1873b5",
|
||||
"parameters": {
|
||||
"html": "={{ $json.html }}",
|
||||
"options": {},
|
||||
"subject": "={{ $json.subject }}",
|
||||
"toEmail": "={{ $json.to }}",
|
||||
"fromEmail": "friedemann.schuetz@posteo.de"
|
||||
},
|
||||
"credentials": {
|
||||
"smtp": {
|
||||
"id": "OFGEnOq5l8U8Lb3U",
|
||||
"name": "SMTP account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.1
|
||||
},
|
||||
{
|
||||
"id": "39d8bb49-d9e9-46e3-89b3-fcbf9345bad8",
|
||||
"name": "Create tasks",
|
||||
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
|
||||
"position": [
|
||||
2340,
|
||||
1040
|
||||
],
|
||||
"parameters": {
|
||||
"name": "create_task",
|
||||
"schemaType": "manual",
|
||||
"workflowId": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": "zSKQLEObdU9RiThI",
|
||||
"cachedResultName": "create_task"
|
||||
},
|
||||
"description": "=Use this tool to create a task. \nFor task creation use only action items for me Friedemann, don't use action items for other participants.",
|
||||
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"items\": {\n \"type\": \"array\",\n \"description\": \"An array of tasks\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"description\": \"The name of the task\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"A detailed description of the task\"\n },\n \"due_date\": {\n \"type\": \"string\",\n \"description\": \"Due Date\"\n },\n \"priority\": {\n \"type\": \"string\",\n \"description\": \"Priority. . Please capitalize first letter\"\n },\n \"project_name\": {\n \"type\": \"string\",\n \"description\": \"Name of the project. Word 'Project' shouldn't be included\"\n }\n },\n \"required\": [\n \"name\",\n \"description\",\n \"due_date\",\n \"priority\"\n ],\n \"additionalProperties\": false\n }\n }\n },\n \"required\": [\n \"items\"\n ],\n \"additionalProperties\": false\n}",
|
||||
"specifyInputSchema": true
|
||||
},
|
||||
"typeVersion": 1.3
|
||||
},
|
||||
{
|
||||
"id": "9fa8eb9e-d4fc-4a2a-9843-2f51055944e9",
|
||||
"name": "Create tasks and follow-up call",
|
||||
"type": "@n8n/n8n-nodes-langchain.agent",
|
||||
"position": [
|
||||
2240,
|
||||
720
|
||||
],
|
||||
"parameters": {
|
||||
"text": "=<system_prompt>\n\nTODAY IS: {{ $now }}\n\nYOU ARE A MEETING ASSISTANT FOR AUTOMATION IN N8N. YOUR TASK IS TO EFFICIENTLY AND PRECISELY PROCESS INFORMATION FROM ZOOM MEETINGS TO GENERATE TO-DOS AND SCHEDULE FOLLOW-UP MEETINGS. YOU HAVE ACCESS TO THE FOLLOWING DATA:\n\n### INPUTS ###\n- **MEETING TITLE**: {{ $('Zoom: Get data of last meeting').item.json.topic }}\n- **PARTICIPANTS**: {{ $('Zoom: Get participants data').item.json.participants[0].name }}\n- **TRANSCRIPT**: {{ $('Format transcript text').item.json.transcript }}\n\n### YOUR TASKS ###\n1. **CREATE TO-DOS**:\n - IDENTIFY TASKS AND TO-DOS IN THE TRANSCRIPT.\n - FORMULATE CLEAR, CONCRETE TASKS.\n - PASS THESE TASKS TO THE TOOL \"Create tasks\" TO SAVE THEM IN CLICKUP. \n - DATA STRUCTURE:\n - **TASK DESCRIPTION**: Brief description of the task.\n - **ASSIGNED PERSON**: First name from the participant list.\n - **DUE DATE**: Use any date mentioned in the transcript; otherwise, set to \"Not specified.\"\n\n2. **CREATE MEETING**:\n - ANALYZE THE TRANSCRIPT TO IDENTIFY INFORMATION ABOUT THE NEXT MEETING (DATE, TIME, AND TOPIC).\n - PASS THIS INFORMATION TO THE TOOL \"Create follow-up call.\"\n - DATA STRUCTURE:\n - **MEETING TITLE**: \"Follow-up: [Meeting Title]\"\n - **DATE AND TIME**: Determined from the transcript or set to \"Next Tuesday at 10:00 AM\" if no information is provided.\n - **PARTICIPANTS**: Add all participants from the list.\n\n### CHAIN OF THOUGHTS ###\n1. **UNDERSTAND**: Read and analyze the provided inputs (title, participants, transcript).\n2. **IDENTIFY**: Extract relevant information for the to-dos and the next meeting.\n3. **DIVIDE**: Split the task into two separate processes: creating to-dos and creating the meeting.\n4. **STRUCTURE**: Format the results in the required structure for the respective tools.\n5. **TRANSMIT**: Pass the data to the designated tools in n8n.\n6. **VERIFY**: Ensure the data is correct and complete.\n\n### WHAT YOU SHOULD NOT DO ###\n- **NEVER**: Create unclear or vague to-dos.\n- **NEVER**: Ignore missing data – use default values where uncertain.\n- **NEVER**: Overlook information from the inputs or make incorrect connections.\n- **NEVER**: Transmit tasks or meetings without proper formatting.\n\n### OUTPUT EXAMPLES ###\n1. **TO-DO**:\n - **TASK DESCRIPTION**: \"Prepare presentation for the next meeting.\"\n - **ASSIGNED PERSON**: \"John Doe.\"\n - **DUE DATE**: \"2025-01-25.\"\n\n2. **MEETING**:\n - **MEETING TITLE**: \"Follow-up: Project Discussion.\"\n - **DATE AND TIME**: \"2025-01-28 at 10:00 AM.\"\n - **PARTICIPANTS**: \"John Doe, Jane Example.\"\n\n### NOTES ###\n- EXECUTE YOUR TASKS WITH THE HIGHEST PRECISION AND CONTEXT SENSITIVITY.\n- RELY ON THE PROVIDED DATA AND DEFAULT VALUES WHERE NECESSARY.\n</system_prompt>\n",
|
||||
"options": {},
|
||||
"promptType": "define"
|
||||
},
|
||||
"typeVersion": 1.7
|
||||
},
|
||||
{
|
||||
"id": "05515784-c99d-4197-9d88-62350bacfb7b",
|
||||
"name": "Create follow-up call",
|
||||
"type": "n8n-nodes-base.microsoftOutlookTool",
|
||||
"position": [
|
||||
2500,
|
||||
1040
|
||||
],
|
||||
"webhookId": "04587796-f979-450d-b9ab-0103cdbf1861",
|
||||
"parameters": {
|
||||
"subject": "={{ $fromAI(\"meeting_name\",\"Meeting name\",\"string\") }}",
|
||||
"resource": "event",
|
||||
"operation": "create",
|
||||
"calendarId": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": "AQMkADAwATNiZmYAZC1jYjE5LWExMzQtMDACLTAwCgBGAAAD1gD8iHcpKEiYQc0w4fCLUgcA-79r8r8ac0aInYGVxRUqCwAAAgEGAAAA-79r8r8ac0aInYGVxRUqCwAAAkH-AAAA",
|
||||
"cachedResultName": "Calendar"
|
||||
},
|
||||
"endDateTime": "={{ $fromAI(\"end_date_time\",\"Date and time of meeting end\",\"string\") }}",
|
||||
"startDateTime": "={{ $fromAI(\"start_date_time\",\"Date and time of meeting start\",\"string\") }}",
|
||||
"descriptionType": "manual",
|
||||
"toolDescription": "=Use tool to create Outlook Calendar Event. Use this tool only when transcript contains information that call should be scheduled.",
|
||||
"additionalFields": {
|
||||
"timeZone": "Europe/Berlin"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"microsoftOutlookOAuth2Api": {
|
||||
"id": "DNMkqql32uwVETij",
|
||||
"name": "Microsoft Outlook account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"id": "2f00c2c6-2389-429c-8c9a-f8f1fbfb6524",
|
||||
"name": "Filter: Last 24 hours",
|
||||
"type": "n8n-nodes-base.filter",
|
||||
"position": [
|
||||
500,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "de097a4f-1f3e-4dc0-9ab6-139311ff4676",
|
||||
"operator": {
|
||||
"type": "dateTime",
|
||||
"operation": "afterOrEquals"
|
||||
},
|
||||
"leftValue": "={{ $json.start_time }}",
|
||||
"rightValue": "={{$now.minus({ hours: 24 }).toISO()}}"
|
||||
},
|
||||
{
|
||||
"id": "b22e726e-b68a-433b-a19b-22bb0b008b9b",
|
||||
"operator": {
|
||||
"type": "dateTime",
|
||||
"operation": "beforeOrEquals"
|
||||
},
|
||||
"leftValue": "={{ $json.start_time }}",
|
||||
"rightValue": "={{ $now }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "fd353a51-eac3-4d04-ae06-dd8e90b82990",
|
||||
"name": "Execute Workflow Trigger",
|
||||
"type": "n8n-nodes-base.executeWorkflowTrigger",
|
||||
"disabled": true,
|
||||
"position": [
|
||||
1280,
|
||||
980
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "40480f97-699b-4a49-867a-54950702af79",
|
||||
"name": "Split Out",
|
||||
"type": "n8n-nodes-base.splitOut",
|
||||
"position": [
|
||||
1500,
|
||||
980
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"fieldToSplitOut": "query.items"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "22e6165f-d7c2-4b23-be63-00c76505cdd3",
|
||||
"name": "ClickUp",
|
||||
"type": "n8n-nodes-base.clickUp",
|
||||
"position": [
|
||||
1720,
|
||||
980
|
||||
],
|
||||
"parameters": {
|
||||
"list": "901207046581",
|
||||
"name": "={{ $json.name }}",
|
||||
"team": "9012366821",
|
||||
"space": "90122025710",
|
||||
"folder": "90123813376",
|
||||
"authentication": "oAuth2",
|
||||
"additionalFields": {
|
||||
"content": "={{ $json.description }}",
|
||||
"dueDate": "={{ $json.due_date }}"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"clickUpOAuth2Api": {
|
||||
"id": "KYxmoCCdfSkwWlXE",
|
||||
"name": "ClickUp account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "742a411e-05cb-4aa0-a541-7b67e613e2bb",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
1060,
|
||||
900
|
||||
],
|
||||
"parameters": {
|
||||
"width": 1000,
|
||||
"height": 280,
|
||||
"content": "## Sub workflow: Create Task in ClickUp"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "ebc5f1df-b417-4977-9700-b71b49a15cbb",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
140,
|
||||
660
|
||||
],
|
||||
"parameters": {
|
||||
"width": 660,
|
||||
"height": 520,
|
||||
"content": "## Welcome to my Zoom AI Meeting Assistant Workflow!\n\n### This workflow has the following sequence:\n\n1. manual trigger (Can be replaced by a scheduled trigger or a webhook)\n2. retrieval of of Zoom meeting data\n3. filter the events of the last 24 hours\n4. retrieval of transcripts and extract of the text\n5. creating a meeting summary, format to html and send per mail\n6. create tasks and follow-up call (if discussed in the meeting) in ClickUp/Outlook (can be replaced by Gmail, Airtable, and so forth) via sub workflow\n\n### The following accesses are required for the workflow:\n- Zoom Workspace (via API and HTTP Request): [Documentation](https://docs.n8n.io/integrations/builtin/credentials/zoom/)\n- Microsoft Outlook: [Documentation](https://docs.n8n.io/integrations/builtin/credentials/microsoft/)\n- ClickUp: [Documentation](https://docs.n8n.io/integrations/builtin/credentials/clickup/)\n- AI API access (e.g. via OpenAI, Anthropic, Google or Ollama)\n- SMTP access data (for sending the mail)\n\nYou can contact me via LinkedIn, if you have any questions: https://www.linkedin.com/in/friedemann-schuetz"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "d9109d09-eb1f-4685-a78b-d17e3dd22438",
|
||||
"name": "Zoom: Get transcripts data",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"onError": "continueErrorOutput",
|
||||
"position": [
|
||||
680,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"url": "=https://api.zoom.us/v2/meetings/{{ $json.id }}/recordings",
|
||||
"options": {},
|
||||
"authentication": "predefinedCredentialType",
|
||||
"nodeCredentialType": "zoomOAuth2Api"
|
||||
},
|
||||
"credentials": {
|
||||
"zoomOAuth2Api": {
|
||||
"id": "MmccxSST1g202tG2",
|
||||
"name": "Zoom account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "fa006183-8f8d-4999-a749-ded5c506b052",
|
||||
"name": "Anthropic Chat Model",
|
||||
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
|
||||
"position": [
|
||||
2080,
|
||||
920
|
||||
],
|
||||
"parameters": {
|
||||
"model": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": "claude-3-7-sonnet-20250219",
|
||||
"cachedResultName": "Claude 3.7 Sonnet"
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"credentials": {
|
||||
"anthropicApi": {
|
||||
"id": "sSOLnAcU9zQcL404",
|
||||
"name": "Anthropic account"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.3
|
||||
},
|
||||
{
|
||||
"id": "bc94960d-36a0-4a52-ba32-7755d19fc441",
|
||||
"name": "Think",
|
||||
"type": "@n8n/n8n-nodes-langchain.toolThink",
|
||||
"position": [
|
||||
2200,
|
||||
920
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "04c96143-5a1b-4599-b5c1-af5990433fa1",
|
||||
"name": "Create meeting summary",
|
||||
"type": "@n8n/n8n-nodes-langchain.agent",
|
||||
"position": [
|
||||
1920,
|
||||
460
|
||||
],
|
||||
"parameters": {
|
||||
"text": "=Create a formal meeting minutes document from the following transcript and meeting details.\n\nMeeting Date: {{ $('Zoom: Get data of last meeting').item.json.start_time }} // This needs to be formatted from the meeting details\nParticipants: {{ $json.participants.map(p => p.name + ' (' + p.user_email + ')').join(', ') }}\n\nTranscript:\n{{ $('Format transcript text').item.json.transcript }}\n\nPlease create the minutes in the following format:\n\nMeeting on [Date]\n\nParticipants:\n[List of participants with email addresses]\n\nSummary of the Meeting:\n[Brief and concise summary of the topics discussed]\n\nTasks:\n- [Task] (Responsible: [Name])\n- ...\n\nImportant Dates:\n- [Date] ([Context])\n- ...\n",
|
||||
"options": {},
|
||||
"promptType": "define"
|
||||
},
|
||||
"typeVersion": 1.9
|
||||
}
|
||||
],
|
||||
"active": false,
|
||||
"pinData": {
|
||||
"Execute Workflow Trigger": [
|
||||
{
|
||||
"json": {
|
||||
"query": {
|
||||
"items": [
|
||||
{
|
||||
"name": "Partner abtelefonieren",
|
||||
"due_date": "2025-01-06",
|
||||
"priority": "High",
|
||||
"description": "Am 6. Januar alle Partner anrufen, um zu klären, ob Interesse an einer weiteren Kooperation besteht und wie diese dargestellt werden kann.",
|
||||
"project_name": "Partnerkooperationen"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"settings": {},
|
||||
"versionId": "56b41429-33c6-45ac-84a4-4dacec001e35",
|
||||
"connections": {
|
||||
"Think": {
|
||||
"ai_tool": [
|
||||
[
|
||||
{
|
||||
"node": "Create meeting summary",
|
||||
"type": "ai_tool",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Create tasks and follow-up call",
|
||||
"type": "ai_tool",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Split Out": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "ClickUp",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Create tasks": {
|
||||
"ai_tool": [
|
||||
[
|
||||
{
|
||||
"node": "Create tasks and follow-up call",
|
||||
"type": "ai_tool",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format to html": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send meeting summary",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Filter: Only 1 item": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Filter: Only 1 item",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Zoom: Get transcript file",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Anthropic Chat Model": {
|
||||
"ai_languageModel": [
|
||||
[
|
||||
{
|
||||
"node": "Create meeting summary",
|
||||
"type": "ai_languageModel",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Create tasks and follow-up call",
|
||||
"type": "ai_languageModel",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Send meeting summary": {
|
||||
"main": [
|
||||
[]
|
||||
]
|
||||
},
|
||||
"Create follow-up call": {
|
||||
"ai_tool": [
|
||||
[
|
||||
{
|
||||
"node": "Create tasks and follow-up call",
|
||||
"type": "ai_tool",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Filter transcript URL": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Filter: Only 1 item",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Filter: Last 24 hours": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Zoom: Get transcripts data",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Create meeting summary": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Sort for mail delivery",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Create tasks and follow-up call",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format transcript text": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Zoom: Get participants data",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Sort for mail delivery": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Format to html",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Workflow Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Split Out",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Zoom: Get transcript file": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Extract text from transcript file",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Zoom: Get transcripts data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Filter transcript URL",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "No Recording/Transcript available",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Zoom: Get participants data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Create meeting summary",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Zoom: Get data of last meeting": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Filter: Last 24 hours",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Create tasks and follow-up call": {
|
||||
"main": [
|
||||
[]
|
||||
]
|
||||
},
|
||||
"Extract text from transcript file": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Format transcript text",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"When clicking ‘Test workflow’": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Zoom: Get data of last meeting",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,676 @@
|
||||
{
|
||||
"id": "k22TSNIZXHaQ9rGr",
|
||||
"meta": {
|
||||
"instanceId": "fb8bc2e315f7f03c97140b30aa454a27bc7883a19000fa1da6e6b571bf56ad6d",
|
||||
"templateCredsSetupCompleted": true
|
||||
},
|
||||
"name": "Clockify Backup Template",
|
||||
"tags": [
|
||||
{
|
||||
"id": "RKga6I6NviNI12bx",
|
||||
"name": "template",
|
||||
"createdAt": "2024-09-19T19:09:21.997Z",
|
||||
"updatedAt": "2024-09-19T19:09:21.997Z"
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "24115363-9a03-4f8a-aa6e-2a9d4247f035",
|
||||
"name": "Extract from File",
|
||||
"type": "n8n-nodes-base.extractFromFile",
|
||||
"position": [
|
||||
660,
|
||||
400
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"operation": "fromJson"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "11aa4b51-98f9-4df8-b2d2-6757fe686894",
|
||||
"name": "Compare Datasets",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"position": [
|
||||
880,
|
||||
280
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "data",
|
||||
"field2": "data"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.3
|
||||
},
|
||||
{
|
||||
"id": "831ad368-6a46-4dd4-bb6c-8ea46200cdf0",
|
||||
"name": "Stop and Error",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
880,
|
||||
700
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "={{ $json.error }}"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "2f838fc8-96bf-4111-aaba-743e0c88b688",
|
||||
"name": "Globals",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
-660,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "6bd5904d-0218-4075-a767-d4b659def9b0",
|
||||
"name": "workspace_id",
|
||||
"type": "string",
|
||||
"value": "={{ $json.id }}"
|
||||
},
|
||||
{
|
||||
"id": "63fa6231-6c5b-414f-b813-18f7dd5c33e9",
|
||||
"name": "github_repo.owner",
|
||||
"type": "string",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"id": "be2530d7-b2b5-41c5-af19-ab8d27f18e2e",
|
||||
"name": "github_repo.name",
|
||||
"type": "string",
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "bea9590e-355e-410a-bc4b-ae777efb9f15",
|
||||
"name": "Set month indexes",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
-440,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "ad278249-5320-4ffa-8d75-e47194c83e58",
|
||||
"name": "monthIndex",
|
||||
"type": "array",
|
||||
"value": "=[0, 1, 2]"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "f541d535-80d9-439d-8543-9c3cb156a5ff",
|
||||
"name": "Split Out indexes",
|
||||
"type": "n8n-nodes-base.splitOut",
|
||||
"position": [
|
||||
-220,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"fieldToSplitOut": "monthIndex"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "76c74727-d338-4a61-9bf2-e97893721995",
|
||||
"name": "Set intervals",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
0,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "7f5ff2ee-b93c-4121-b3dc-ce592513db88",
|
||||
"name": "reportName",
|
||||
"type": "string",
|
||||
"value": "=detailed_report_{{ $now.minus($json.monthIndex, 'month').format('yyyy-MM') }}"
|
||||
},
|
||||
{
|
||||
"id": "ea571bdb-8f51-4852-9fda-55ff1a929d1f",
|
||||
"name": "startDate",
|
||||
"type": "string",
|
||||
"value": "={{ $now.minus($json.monthIndex, 'month').startOf('month').format('yyyy-MM-dd') }}"
|
||||
},
|
||||
{
|
||||
"id": "e88726c4-1eb8-4f29-9805-7b0a5ee484a4",
|
||||
"name": "endDate",
|
||||
"type": "string",
|
||||
"value": "={{ $now.minus($json.monthIndex, 'month').endOf('month').format('yyyy-MM-dd') }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "6d5e917e-68ac-4dbd-98be-4c8ad97fa54a",
|
||||
"name": "Skip empty reports",
|
||||
"type": "n8n-nodes-base.filter",
|
||||
"position": [
|
||||
880,
|
||||
500
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "f6c69f9b-9e78-4a1e-af33-a1197f35e970",
|
||||
"operator": {
|
||||
"type": "array",
|
||||
"operation": "notEmpty",
|
||||
"singleValue": true
|
||||
},
|
||||
"leftValue": "={{ $json.timeentries }}",
|
||||
"rightValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "60c7a408-74d3-4c6c-ac78-1ed1071e873e",
|
||||
"name": "Get first workspace",
|
||||
"type": "n8n-nodes-base.clockify",
|
||||
"position": [
|
||||
-880,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"limit": 1,
|
||||
"resource": "workspace"
|
||||
},
|
||||
"credentials": {
|
||||
"clockifyApi": {
|
||||
"id": "CMJ0LAYOs143GAXw",
|
||||
"name": "Clockify (octionictest)"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "824bf2c6-9159-40ec-83f3-3f0b8d87c208",
|
||||
"name": "Get detailed monthly report",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
220,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"url": "=https://reports.api.clockify.me/v1/workspaces/{{ $('Globals').item.json.workspace_id }}/reports/detailed",
|
||||
"method": "POST",
|
||||
"options": {},
|
||||
"jsonBody": "={\n \"dateRangeStart\": \"{{ $json.startDate }}T00:00:00Z\",\n \"dateRangeEnd\": \"{{ $json.endDate }}T23:59:59.999Z\",\n \"detailedFilter\": {\n \"page\": 1,\n \"pageSize\": 50\n },\n \"exportType\": \"json\"\n}",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"authentication": "predefinedCredentialType",
|
||||
"nodeCredentialType": "clockifyApi"
|
||||
},
|
||||
"credentials": {
|
||||
"clockifyApi": {
|
||||
"id": "CMJ0LAYOs143GAXw",
|
||||
"name": "Clockify (octionictest)"
|
||||
}
|
||||
},
|
||||
"typeVersion": 4.2
|
||||
},
|
||||
{
|
||||
"id": "f9323c68-c70f-4f22-ae18-916d5fc1b264",
|
||||
"name": "Check if file exists in GitHub",
|
||||
"type": "n8n-nodes-base.github",
|
||||
"onError": "continueErrorOutput",
|
||||
"position": [
|
||||
440,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"owner": {
|
||||
"__rl": true,
|
||||
"mode": "name",
|
||||
"value": "={{ $('Globals').first().json.github_repo.owner }}"
|
||||
},
|
||||
"filePath": "=reports/{{ $('Set intervals').item.json.reportName }}",
|
||||
"resource": "file",
|
||||
"operation": "get",
|
||||
"repository": {
|
||||
"__rl": true,
|
||||
"mode": "name",
|
||||
"value": "={{ $('Globals').first().json.github_repo.name }}"
|
||||
},
|
||||
"additionalParameters": {}
|
||||
},
|
||||
"credentials": {
|
||||
"githubApi": {
|
||||
"id": "Eb9yCfVJGJvXD05z",
|
||||
"name": "GitHub (n8n-test-01)"
|
||||
}
|
||||
},
|
||||
"retryOnFail": false,
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "41877a6a-ba5b-43bd-8ca3-f8402793685f",
|
||||
"name": "Point to new data",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
660,
|
||||
200
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "00d2885f-451e-436e-8852-b9ad086d231b",
|
||||
"name": "data",
|
||||
"type": "array",
|
||||
"value": "={{ $('Get detailed monthly report').item.json.timeentries }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "9f448921-5b9d-4937-a7d9-00a62b1fba99",
|
||||
"name": "Check for 404 error message",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
660,
|
||||
600
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "6b34c09d-0136-433c-856d-b29a0c3aac34",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "contains"
|
||||
},
|
||||
"leftValue": "={{ $json.error }}",
|
||||
"rightValue": "could not be found"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "900905ed-cff6-4ebb-b0da-67db9f02b301",
|
||||
"name": "Update file in GitHub",
|
||||
"type": "n8n-nodes-base.github",
|
||||
"position": [
|
||||
1100,
|
||||
180
|
||||
],
|
||||
"parameters": {
|
||||
"owner": {
|
||||
"__rl": true,
|
||||
"mode": "name",
|
||||
"value": "={{ $('Globals').first().json.github_repo.owner }}"
|
||||
},
|
||||
"filePath": "=reports/{{ $('Set intervals').item.json.reportName }}",
|
||||
"resource": "file",
|
||||
"operation": "edit",
|
||||
"repository": {
|
||||
"__rl": true,
|
||||
"mode": "name",
|
||||
"value": "={{ $('Globals').first().json.github_repo.name }}"
|
||||
},
|
||||
"fileContent": "={{ JSON.stringify($json.data, null, 2) }}",
|
||||
"commitMessage": "Update report"
|
||||
},
|
||||
"credentials": {
|
||||
"githubApi": {
|
||||
"id": "Eb9yCfVJGJvXD05z",
|
||||
"name": "GitHub (n8n-test-01)"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "b928cdb2-b21a-45ff-9bc6-9be483891c4c",
|
||||
"name": "Create file in GitHub",
|
||||
"type": "n8n-nodes-base.github",
|
||||
"position": [
|
||||
1100,
|
||||
500
|
||||
],
|
||||
"parameters": {
|
||||
"owner": {
|
||||
"__rl": true,
|
||||
"mode": "name",
|
||||
"value": "={{ $('Globals').first().json.github_repo.owner }}"
|
||||
},
|
||||
"filePath": "=reports/{{ $('Set intervals').item.json.reportName }}",
|
||||
"resource": "file",
|
||||
"repository": {
|
||||
"__rl": true,
|
||||
"mode": "name",
|
||||
"value": "={{ $('Globals').first().json.github_repo.name }}"
|
||||
},
|
||||
"fileContent": "={{ JSON.stringify($json.timeentries, null, 2) }}",
|
||||
"commitMessage": "Create report"
|
||||
},
|
||||
"credentials": {
|
||||
"githubApi": {
|
||||
"id": "Eb9yCfVJGJvXD05z",
|
||||
"name": "GitHub (n8n-test-01)"
|
||||
}
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "04a5b42d-ea1f-4b32-98b5-953e22b26819",
|
||||
"name": "Schedule Trigger",
|
||||
"type": "n8n-nodes-base.scheduleTrigger",
|
||||
"position": [
|
||||
-1100,
|
||||
480
|
||||
],
|
||||
"parameters": {
|
||||
"rule": {
|
||||
"interval": [
|
||||
{
|
||||
"triggerAtHour": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 1.2
|
||||
},
|
||||
{
|
||||
"id": "4728f389-df04-4f8d-a436-ac06508d28ba",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-720,
|
||||
260
|
||||
],
|
||||
"parameters": {
|
||||
"width": 220,
|
||||
"height": 380,
|
||||
"content": "## Set Globals\n- Define the repository owner (username / organization) and repository name\n- By default the fist available Clockify workspace ID is set. This can be overridden here."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "2e31df0a-1e67-4a9a-8dc1-42360b4da978",
|
||||
"name": "Sticky Note4",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-1160,
|
||||
360
|
||||
],
|
||||
"parameters": {
|
||||
"width": 220,
|
||||
"height": 280,
|
||||
"content": "## Set trigger\nBy default this workflow runs once a day."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "696721c6-25fc-48f9-b0f5-53d1b6462183",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-500,
|
||||
300
|
||||
],
|
||||
"parameters": {
|
||||
"width": 220,
|
||||
"height": 340,
|
||||
"content": "## Set Scope (optional)\nBy default the last three moths are being backed up.\n_0 = current month, 1 = last month, etc._"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "a0ebb845-7472-40ec-b2b5-abc2f118b0e1",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
160,
|
||||
360
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 220,
|
||||
"height": 280,
|
||||
"content": "A detailed report is being retrieved for every month across all entries in the workspace."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "feb9f194-4c9d-41c8-9b46-3759dcdae9d5",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
380,
|
||||
100
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 920,
|
||||
"height": 780,
|
||||
"content": "The reports are created or updated in GitHub.\n**It is essential to back up previous months as well, as values like tags may still change over time.**"
|
||||
},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"active": false,
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "34ab93f2-a965-42ac-bd44-478c19a0f7d6",
|
||||
"connections": {
|
||||
"Globals": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set month indexes",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set intervals": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get detailed monthly report",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Compare Datasets": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Update file in GitHub",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[],
|
||||
[]
|
||||
]
|
||||
},
|
||||
"Schedule Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get first workspace",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Extract from File": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare Datasets",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Point to new data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare Datasets",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set month indexes": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Split Out indexes",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Split Out indexes": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set intervals",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Skip empty reports": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Create file in GitHub",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get first workspace": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Globals",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check for 404 error message": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Skip empty reports",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Stop and Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get detailed monthly report": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check if file exists in GitHub",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check if file exists in GitHub": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Point to new data",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Extract from File",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Check for 404 error message",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,439 @@
|
||||
{
|
||||
"id": "qAzZekQuABuH8uho",
|
||||
"meta": {
|
||||
"instanceId": "fb8bc2e315f7f03c97140b30aa454a27bc7883a19000fa1da6e6b571bf56ad6d"
|
||||
},
|
||||
"name": "Retry on fail except for known error Template",
|
||||
"tags": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "fa6fb462-8c1b-4cab-a9f6-876e67688786",
|
||||
"name": "Retry limit reached",
|
||||
"type": "n8n-nodes-base.stopAndError",
|
||||
"position": [
|
||||
-940,
|
||||
500
|
||||
],
|
||||
"parameters": {
|
||||
"errorMessage": "Retry limit reached"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "9627165d-1854-4a4f-b840-721f8d779b89",
|
||||
"name": "Set tries",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
-940,
|
||||
260
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "cd93a7f6-4c06-4e8a-8d0d-e812c5ec4bc5",
|
||||
"name": "tries",
|
||||
"type": "number",
|
||||
"value": "={{ $json.tries || 0 }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"includeOtherFields": true
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "466efd16-4922-4e61-bc81-d8e8a1d8ea61",
|
||||
"name": "Update tries",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [
|
||||
-60,
|
||||
500
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "df3c9b29-afa6-4e08-868d-5b7e8202eefa",
|
||||
"name": "tries",
|
||||
"type": "number",
|
||||
"value": "={{ $('Set tries').item.json.tries + 1 }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 3.4
|
||||
},
|
||||
{
|
||||
"id": "a787761f-0a9d-4834-9a65-ac3b9a65b23e",
|
||||
"name": "Wait",
|
||||
"type": "n8n-nodes-base.wait",
|
||||
"position": [
|
||||
-280,
|
||||
500
|
||||
],
|
||||
"webhookId": "9d3b561f-4afd-478c-8f6e-60641d4f1d0b",
|
||||
"parameters": {},
|
||||
"typeVersion": 1.1
|
||||
},
|
||||
{
|
||||
"id": "ff46ce53-69ca-4f88-8cc9-21b8d1e5557a",
|
||||
"name": "Catch known error",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
-500,
|
||||
380
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "6a379b06-0b04-4ae4-9bf9-394bd40744b7",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "contains"
|
||||
},
|
||||
"leftValue": "={{ $json.error }}",
|
||||
"rightValue": "could not be found"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "0e9c282a-b521-4549-8ad5-9783b4d614b3",
|
||||
"name": "Replace Me",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"onError": "continueErrorOutput",
|
||||
"position": [
|
||||
-720,
|
||||
260
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "3b2b6839-65b9-4b0e-8e10-2010014fc8d9",
|
||||
"name": "Success",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"position": [
|
||||
-500,
|
||||
140
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "8d972714-8dcb-4ad6-8b5f-fb30a5f3294f",
|
||||
"name": "Known Error",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"position": [
|
||||
-280,
|
||||
260
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "e98cdc4a-73a4-41d1-bf5e-2a3bcfbf23af",
|
||||
"name": "Sticky Note",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-560,
|
||||
280
|
||||
],
|
||||
"parameters": {
|
||||
"width": 220,
|
||||
"height": 240,
|
||||
"content": "## Set filter\nFilter by status code or error message."
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "e5b76cd3-d90a-4d4b-a659-ff142558cbac",
|
||||
"name": "Sticky Note1",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-780,
|
||||
80
|
||||
],
|
||||
"parameters": {
|
||||
"width": 220,
|
||||
"height": 320,
|
||||
"content": "## Replace Node\nReplace this by the Node which retrieves the admired data.\nEnable error branch in Node Settings and connect the outputs like in this example"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "7ca409e6-7faf-48d5-972e-abbba3f011ef",
|
||||
"name": "Sticky Note2",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-1220,
|
||||
420
|
||||
],
|
||||
"parameters": {
|
||||
"width": 220,
|
||||
"height": 220,
|
||||
"content": "## Set max tries\nChange if needed, default is 3"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "a13168eb-c4d1-46dd-857b-9a5e13ed1059",
|
||||
"name": "Manual Trigger",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"position": [
|
||||
-1160,
|
||||
260
|
||||
],
|
||||
"parameters": {},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "44c17908-96df-471b-97fc-9ce4c3acb3bb",
|
||||
"name": "Sticky Note3",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-340,
|
||||
400
|
||||
],
|
||||
"parameters": {
|
||||
"width": 220,
|
||||
"height": 240,
|
||||
"content": "## Set Wait\nChange duration if needed, default is 5s"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "da7413f0-7962-4cf1-90ad-168cfc3d4c0d",
|
||||
"name": "Sticky Note4",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-560,
|
||||
80
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 220,
|
||||
"height": 200,
|
||||
"content": "Continue here, if the request succeeded"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "e95c4b6a-2c63-4916-a239-91463728262a",
|
||||
"name": "Sticky Note5",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-340,
|
||||
200
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 220,
|
||||
"height": 200,
|
||||
"content": "Continue here, if the request failed"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "8d8f7df0-35e3-4b94-96a3-6d4593732d0e",
|
||||
"name": "Sticky Note6",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-1000,
|
||||
420
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 220,
|
||||
"height": 220,
|
||||
"content": "Stop here, if all tries have failed"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "893b3e51-f30f-4e2f-9e96-e1fc6f8dd0a3",
|
||||
"name": "Sticky Note7",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-1000,
|
||||
200
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 220,
|
||||
"height": 220,
|
||||
"content": "Define counter for tries"
|
||||
},
|
||||
"typeVersion": 1
|
||||
},
|
||||
{
|
||||
"id": "cd1b1abb-dbd3-4023-8a6b-49c4ff5510a8",
|
||||
"name": "If tries left",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [
|
||||
-1160,
|
||||
500
|
||||
],
|
||||
"parameters": {
|
||||
"options": {},
|
||||
"conditions": {
|
||||
"options": {
|
||||
"version": 2,
|
||||
"leftValue": "",
|
||||
"caseSensitive": true,
|
||||
"typeValidation": "strict"
|
||||
},
|
||||
"combinator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "b18f784a-4386-4ced-a9e1-ce5a21ad036e",
|
||||
"operator": {
|
||||
"type": "number",
|
||||
"operation": "lt"
|
||||
},
|
||||
"leftValue": "={{ $json.tries }}",
|
||||
"rightValue": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"typeVersion": 2.2
|
||||
},
|
||||
{
|
||||
"id": "ccce734b-c726-4b0a-9d37-7bd6df90e840",
|
||||
"name": "Sticky Note8",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"position": [
|
||||
-120,
|
||||
440
|
||||
],
|
||||
"parameters": {
|
||||
"color": 7,
|
||||
"width": 220,
|
||||
"height": 220,
|
||||
"content": "Update counter for tries"
|
||||
},
|
||||
"typeVersion": 1
|
||||
}
|
||||
],
|
||||
"active": false,
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "ad610eea-ad27-4a3b-b662-edea474bc5ff",
|
||||
"connections": {
|
||||
"Wait": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Update tries",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set tries": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Replace Me",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Replace Me": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Success",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Catch known error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Update tries": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "If tries left",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"If tries left": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set tries",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Retry limit reached",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Manual Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set tries",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Catch known error": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Known Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Wait",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user